Commit c4aab480 authored by Alexander Nozdrin's avatar Alexander Nozdrin

Merge. Backport WL#4085 from 6.0.

parents dea2a8da 0c3e1aa1
......@@ -816,7 +816,6 @@ sub command_line_setup {
'combination=s' => \@opt_combinations,
'skip-combinations' => \&collect_option,
'experimental=s' => \$opt_experimental,
'skip-im' => \&ignore_option,
# Specify ports
'build-thread|mtr-build-thread=i' => \$opt_build_thread,
......
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
SHOW INSTANCES;
instance_name state
mysqld1 XXXXX
mysqld2 offline
--> Listing users...
im_admin
==> Adding user 'testuser'...
--> IM password file:
testuser:*0D3CED9BEC10A777AEC23CCC353A8C08A633045E
im_admin:*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295
--> EOF
--> Printing out line for 'testuser'...
testuser:*0D3CED9BEC10A777AEC23CCC353A8C08A633045E
--> Listing users...
im_admin
testuser
==> Changing the password of 'testuser'...
--> IM password file:
im_admin:*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295
testuser:*39C549BDECFBA8AFC3CE6B948C9359A0ECE08DE2
--> EOF
--> Printing out line for 'testuser'...
testuser:*39C549BDECFBA8AFC3CE6B948C9359A0ECE08DE2
--> Listing users...
testuser
im_admin
==> Dropping user 'testuser'...
--> IM password file:
im_admin:*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295
--> EOF
--> Listing users...
im_admin
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
SHOW INSTANCES;
instance_name state
mysqld1 XXXXX
mysqld2 offline
Killing the process...
Waiting...
Success: the process was restarted.
Success: server is ready to accept connection on socket.
--------------------------------------------------------------------
-- Test for BUG#12751
--------------------------------------------------------------------
START INSTANCE mysqld2;
Success: the process has been started.
Killing the process...
Waiting...
Success: the process was restarted.
Success: server is ready to accept connection on socket.
SHOW INSTANCE STATUS mysqld1;
instance_name state version_number version mysqld_compatible
mysqld1 STATE VERSION_NUMBER VERSION no
STOP INSTANCE mysqld2;
Success: the process has been stopped.
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
SHOW INSTANCES;
instance_name state
mysqld1 XXXXX
mysqld2 offline
--------------------------------------------------------------------
server_id = 1
server_id = 2
--------------------------------------------------------------------
CREATE INSTANCE mysqld3
server_id = 3,
socket = "$MYSQL_TMP_DIR/mysqld_3.sock";
SHOW INSTANCES;
instance_name state
mysqld3 offline
mysqld2 offline
mysqld1 online
--------------------------------------------------------------------
server_id = 1
server_id = 2
server_id=3
--------------------------------------------------------------------
CREATE INSTANCE mysqld1;
ERROR HY000: Instance already exists
CREATE INSTANCE mysqld2;
ERROR HY000: Instance already exists
CREATE INSTANCE mysqld3;
ERROR HY000: Instance already exists
--------------------------------------------------------------------
nonguarded
--------------------------------------------------------------------
CREATE INSTANCE mysqld4
nonguarded,
server_id = 4,
socket = "$MYSQL_TMP_DIR/mysqld_4.sock";
SHOW INSTANCES;
instance_name state
mysqld3 offline
mysqld4 offline
mysqld1 online
mysqld2 offline
--------------------------------------------------------------------
nonguarded
nonguarded
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
CREATE INSTANCE mysqld5
test-A = 000,
test-B = test,
server_id = 5,
socket = "$MYSQL_TMP_DIR/mysqld_5.sock";
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld4 offline
mysqld5 offline
mysqld2 offline
mysqld3 offline
--------------------------------------------------------------------
test-A=000
--------------------------------------------------------------------
test-B=test
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
CREATE INSTANCE mysqld6
test-C1 = 10 ,
test-C2 = 02 ,
server_id = 6,
socket = "$MYSQL_TMP_DIR/mysqld_6.sock";
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld2 offline
mysqld5 offline
mysqld6 offline
mysqld3 offline
mysqld4 offline
--------------------------------------------------------------------
test-C1=10
--------------------------------------------------------------------
test-C2=02
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
CREATE INSTANCE mysqld7 test-D = test-D-value ;
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld2 offline
mysqld5 offline
mysqld6 offline
mysqld3 offline
mysqld4 offline
CREATE INSTANCE mysqld8 test-E 0 ;
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld2 offline
mysqld5 offline
mysqld6 offline
mysqld3 offline
mysqld4 offline
CREATE INSTANCE mysqld8 test-F = ;
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld2 offline
mysqld5 offline
mysqld6 offline
mysqld3 offline
mysqld4 offline
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
CREATE INSTANCE mysqld9
test-1=" hello world ",
test-2=' ',
server_id = 9,
socket = "$MYSQL_TMP_DIR/mysqld_9.sock";
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld2 offline
mysqld5 offline
mysqld6 offline
mysqld3 offline
mysqld4 offline
mysqld9 offline
CREATE INSTANCE mysqld10
test-3='\b\babc\sdef',
server_id = 10,
socket = "$MYSQL_TMP_DIR/mysqld_10.sock";
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld9 offline
mysqld5 offline
mysqld6 offline
mysqld3 offline
mysqld4 offline
mysqld10 offline
mysqld2 offline
CREATE INSTANCE mysqld11
test-4='abc\tdef',
test-5='abc\ndef',
server_id = 11,
socket = "$MYSQL_TMP_DIR/mysqld_11.sock";
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld11 offline
mysqld5 offline
mysqld6 offline
mysqld3 offline
mysqld4 offline
mysqld10 offline
mysqld2 offline
mysqld9 offline
CREATE INSTANCE mysqld12
test-6="abc\rdef",
test-7="abc\\def",
server_id = 12,
socket = "$MYSQL_TMP_DIR/mysqld_12.sock";
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld9 offline
mysqld5 offline
mysqld6 offline
mysqld3 offline
mysqld4 offline
mysqld10 offline
mysqld2 offline
mysqld12 offline
mysqld11 offline
CREATE INSTANCE mysqld13 test-bad=' \ ';
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld9 offline
mysqld5 offline
mysqld6 offline
mysqld3 offline
mysqld4 offline
mysqld10 offline
mysqld2 offline
mysqld12 offline
mysqld11 offline
--------------------------------------------------------------------
test-1= hello world
--------------------------------------------------------------------
test-2=
--------------------------------------------------------------------
test-3=abc def
--------------------------------------------------------------------
test-4=abc def
--------------------------------------------------------------------
test-5=abc
--------------------------------------------------------------------
test-6=abc def
--------------------------------------------------------------------
test-7=abc\def
--------------------------------------------------------------------
--------------------------------------------------------------------
CREATE INSTANCE qqq1;
ERROR HY000: Malformed instance name.
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
SHOW INSTANCES;
instance_name state
mysqld1 XXXXX
mysqld2 offline
--------------------------------------------------------------------
-- 1.1.2.
--------------------------------------------------------------------
START INSTANCE mysqld2;
Success: the process has been started.
SHOW VARIABLES LIKE 'port';
Variable_name Value
port IM_MYSQLD2_PORT
--------------------------------------------------------------------
-- 1.1.3.
--------------------------------------------------------------------
STOP INSTANCE mysqld2;
Success: the process has been stopped.
--------------------------------------------------------------------
-- 1.1.4.
--------------------------------------------------------------------
START INSTANCE mysqld3;
ERROR HY000: Unknown instance name
START INSTANCE mysqld1;
ERROR HY000: The instance is already started
--------------------------------------------------------------------
-- 1.1.5.
--------------------------------------------------------------------
STOP INSTANCE mysqld3;
ERROR HY000: Unknown instance name
--------------------------------------------------------------------
-- 1.1.6.
--------------------------------------------------------------------
Killing the process...
Waiting...
Success: the process was restarted.
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld2 offline
--------------------------------------------------------------------
-- 1.1.7.
--------------------------------------------------------------------
START INSTANCE mysqld2;
Success: the process has been started.
Killing the process...
Waiting...
Success: the process was killed.
--------------------------------------------------------------------
-- 1.1.8.
--------------------------------------------------------------------
SHOW INSTANCE STATUS;
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
--------------------------------------------------------------------
-- BUG#12813
--------------------------------------------------------------------
START INSTANCE mysqld1,mysqld2,mysqld3;
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
STOP INSTANCE mysqld1,mysqld2,mysqld3;
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
STOP INSTANCE mysqld2;
ERROR HY000: Cannot stop instance. Perhaps the instance is not started, or was started manually, so IM cannot find the pidfile.
End of 5.0 tests
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
SHOW INSTANCES;
instance_name state
mysqld1 XXXXX
mysqld2 offline
UNSET mysqld1.server_id;
ERROR HY000: The instance is active. Stop the instance first
SET mysqld1.server_id = 11;
ERROR HY000: The instance is active. Stop the instance first
CREATE INSTANCE mysqld3
datadir = '/',
server_id = 3,
socket = "$MYSQL_TMP_DIR/mysqld_3.sock";
START INSTANCE mysqld3;
UNSET mysqld3.server_id;
ERROR HY000: The instance is active. Stop the instance first
SET mysqld3.server_id = 11;
ERROR HY000: The instance is active. Stop the instance first
STOP INSTANCE mysqld3;
SHOW INSTANCE STATUS mysqld3;
instance_name state version_number version mysqld_compatible
mysqld3 offline VERSION_NUMBER VERSION no
UNSET mysqld2.server_id;
UNSET mysqld2.server_id;
SHOW INSTANCE OPTIONS mysqld2;
option_name value
instance_name option_value
socket option_value
pid-file option_value
port option_value
datadir option_value
log option_value
log-error option_value
log-slow-queries option_value
language option_value
character-sets-dir option_value
basedir option_value
shutdown-delay option_value
skip-stack-trace option_value
loose-skip-innodb option_value
loose-skip-ndbcluster option_value
nonguarded option_value
log-output option_value
SET mysqld2.server_id = 2;
SET mysqld2.server_id = 2;
SHOW INSTANCE OPTIONS mysqld2;
option_name value
instance_name option_value
socket option_value
pid-file option_value
port option_value
datadir option_value
log option_value
log-error option_value
log-slow-queries option_value
language option_value
character-sets-dir option_value
basedir option_value
shutdown-delay option_value
skip-stack-trace option_value
loose-skip-innodb option_value
loose-skip-ndbcluster option_value
nonguarded option_value
log-output option_value
server_id option_value
UNSET mysqld2.server_id = 11;
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
SET mysqld2.aaa, mysqld3.bbb, mysqld2.ccc = 0010, mysqld3.ddd = 0020;
--------------------------------------------------------------------
aaa
--------------------------------------------------------------------
bbb
--------------------------------------------------------------------
ccc=0010
--------------------------------------------------------------------
ddd=0020
--------------------------------------------------------------------
UNSET mysqld2.aaa, mysqld3.bbb, mysqld2.ccc, mysqld3.ddd;
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
SET mysqld2.aaa, mysqld3.bbb, mysqld.ccc = 0010;
ERROR HY000: Unknown instance name
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
SET mysqld2.aaa, mysqld3.bbb, mysqld1.ccc = 0010;
ERROR HY000: The instance is active. Stop the instance first
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
UNSET mysqld2.server_id, mysqld3.server_id, mysqld.ccc;
ERROR HY000: Unknown instance name
--------------------------------------------------------------------
server_id = 1
server_id=2
server_id=3
--------------------------------------------------------------------
UNSET mysqld2.server_id, mysqld3.server_id, mysqld1.ccc;
ERROR HY000: The instance is active. Stop the instance first
--------------------------------------------------------------------
server_id = 1
server_id=2
server_id=3
--------------------------------------------------------------------
DROP INSTANCE mysqld3;
SET mysqld2.server_id=222;
SET mysqld2.server_id = 222;
SET mysqld2.server_id = 222 ;
SET mysqld2 . server_id = 222 ;
SET mysqld2 . server_id = 222 , mysqld2 . aaa , mysqld2 . bbb ;
--------------------------------------------------------------------
server_id = 1
server_id=222
--------------------------------------------------------------------
aaa
--------------------------------------------------------------------
bbb
--------------------------------------------------------------------
UNSET mysqld2 . aaa , mysqld2 . bbb ;
--------------------------------------------------------------------
server_id = 1
server_id=222
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
--------------------------------------------------------------------
server_id = 1
server_id=222
--------------------------------------------------------------------
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
SHOW INSTANCES;
instance_name state
mysqld1 online
mysqld2 offline
FLUSH INSTANCES;
ERROR HY000: At least one instance is active. Stop all instances first
STOP INSTANCE mysqld1;
SHOW INSTANCES;
instance_name state
mysqld1 offline
mysqld2 offline
FLUSH INSTANCES;
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
SHOW INSTANCES;
instance_name state
mysqld1 XXXXX
mysqld2 offline
SHOW INSTANCE OPTIONS mysqld1;
option_name value
instance_name VALUE
socket VALUE
pid-file VALUE
port VALUE
datadir VALUE
log VALUE
log-error VALUE
log-slow-queries VALUE
language VALUE
character-sets-dir VALUE
basedir VALUE
server_id VALUE
shutdown-delay VALUE
skip-stack-trace VALUE
loose-skip-innodb VALUE
loose-skip-ndbcluster VALUE
log-output VALUE
SHOW INSTANCE OPTIONS mysqld2;
option_name value
instance_name VALUE
socket VALUE
pid-file VALUE
port VALUE
datadir VALUE
log VALUE
log-error VALUE
log-slow-queries VALUE
language VALUE
character-sets-dir VALUE
basedir VALUE
server_id VALUE
shutdown-delay VALUE
skip-stack-trace VALUE
loose-skip-innodb VALUE
loose-skip-ndbcluster VALUE
nonguarded VALUE
log-output VALUE
START INSTANCE mysqld2;
Success: the process has been started.
STOP INSTANCE mysqld2;
Success: the process has been stopped.
SHOW mysqld1 LOG FILES;
Logfile Path File size
ERROR LOG PATH FILE_SIZE
GENERAL LOG PATH FILE_SIZE
SLOW LOG PATH FILE_SIZE
SHOW mysqld2 LOG FILES;
Logfile Path File size
ERROR LOG PATH FILE_SIZE
GENERAL LOG PATH FILE_SIZE
SLOW LOG PATH FILE_SIZE
SHOW mysqld1 LOG ERROR 10;
Log
LOG_DATA
SHOW mysqld1 LOG SLOW 10;
Log
LOG_DATA
SHOW mysqld1 LOG GENERAL 10;
Log
LOG_DATA
SHOW mysqld1 LOG ERROR 10, 2;
Log
LOG_DATA
SHOW mysqld1 LOG SLOW 10, 2;
Log
LOG_DATA
SHOW mysqld1 LOG GENERAL 10, 2;
Log
LOG_DATA
SHOW mysqld2 LOG ERROR 10;
Log
LOG_DATA
SHOW mysqld2 LOG SLOW 10;
Log
LOG_DATA
SHOW mysqld2 LOG GENERAL 10;
Log
LOG_DATA
SHOW mysqld2 LOG ERROR 10, 2;
Log
LOG_DATA
SHOW mysqld2 LOG SLOW 10, 2;
Log
LOG_DATA
SHOW mysqld2 LOG GENERAL 10, 2;
Log
LOG_DATA
##############################################################################
#
# List the test cases that are to be disabled temporarily.
#
# Separate the test case name and the comment with ':'.
#
# <testcasename> : BUG#<xxxx> <date disabled> <disabler> <comment>
#
# Do not use any TAB characters for whitespace.
#
##############################################################################
im_options : Bug#20294 2006-07-24 stewart Instance manager test im_options fails randomly
im_daemon_life_cycle : Bug#20294 2007-05-14 alik Instance manager tests fail randomly
im_cmd_line : Bug#20294 2007-05-14 alik Instance manager tests fail randomly
im_utils : Bug#20294 2007-05-30 alik Instance manager tests fail randomly
im_instance_conf : Bug#20294 2007-05-30 alik Instance manager tests fail randomly
im_life_cycle : BUG#27851 Instance manager dies on ASSERT in ~Thread_registry() or from not being able to close a mysqld instance.
im_instance_conf : BUG#28743 Instance manager generates warnings in test suite
im_utils : BUG#28743 Instance manager generates warnings in test suite
# This file is intended to be used in each IM-test. It contains stamements,
# that ensure that starting conditions (environment) for the IM-test are as
# expected.
# Check the running instances.
--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
--connection mysql1_con
SHOW VARIABLES LIKE 'server_id';
--source include/not_windows.inc
--connection default
# Let IM detect that mysqld1 is online. This delay should be longer than
# monitoring interval.
--sleep 2
# Check that IM understands that mysqld1 is online, while mysqld2 is
# offline.
--replace_result starting XXXXX online XXXXX
SHOW INSTANCES;
###########################################################################
#
# Tests for user-management command-line options.
#
###########################################################################
--source suite/im/t/im_check_env.inc
###########################################################################
# List users so we are sure about starting conditions.
--echo --> Listing users...
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --list-users 2>&1 >/dev/null
--echo
# Add a new user.
--echo ==> Adding user 'testuser'...
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --add-user --username=testuser --password=abc 2>&1 >/dev/null
--echo
--echo --> IM password file:
--exec cat $IM_PASSWORD_PATH
--echo --> EOF
--echo
--echo --> Printing out line for 'testuser'...
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --print-password-line --username=testuser --password=abc | tail -2 | head -1
--echo
--echo --> Listing users...
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --list-users 2>&1 >/dev/null
--echo
# Edit user's attributes.
--echo ==> Changing the password of 'testuser'...
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --edit-user --username=testuser --password=xyz 2>&1 >/dev/null
--echo
--echo --> IM password file:
--exec cat $IM_PASSWORD_PATH
--echo --> EOF
--echo
--echo --> Printing out line for 'testuser'...
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --print-password-line --username=testuser --password=xyz | tail -2 | head -1
--echo
--echo --> Listing users...
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --list-users 2>&1 >/dev/null
--echo
# Drop user.
--echo ==> Dropping user 'testuser'...
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --drop-user --username=testuser 2>&1 >/dev/null
--echo
--echo --> IM password file:
--exec cat $IM_PASSWORD_PATH
--echo --> EOF
--echo
--echo --> Listing users...
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --list-users 2>&1 >/dev/null
--echo
--run-as-service
--log=$MYSQLTEST_VARDIR/log/im.log
--monitoring-interval=1
let $UTIL=$MYSQL_TEST_DIR/suite/im/t;
###########################################################################
#
# This file contains test for (1.2) test suite.
#
# Consult WL#2789 for more information.
#
###########################################################################
--exec $UTIL/log.sh im_daemon_life_cycle im_daemon_life_cycle.imtest started.
###########################################################################
--source suite/im/t/im_check_env.inc
# Turn on reconnect, not on by default anymore.
--enable_reconnect
###########################################################################
#
# The main daemon-life-cycle test case -- check that IM-angel will restart
# IM-main if it got killed:
# - kill IM-main and check that IM-angel will restart it;
# - wait for IM-main to start accepting connections before continue test
# case;
#
# NOTE: timeout is 55 seconds. Timeout should be more than shutdown-delay
# specified for managed MySQL instance. Now shutdown-delay is 10 seconds
# (set in mysql-test-run.pl). So, 55 seconds should be enough to make 5
# attempts.
#
###########################################################################
--exec $UTIL/log.sh im_daemon_life_cycle Main-test: starting...
--exec $UTIL/log.sh im_daemon_life_cycle Killing IM-main...
--exec $UTIL/kill_n_check.sh $IM_PATH_PID restarted 55 im_daemon_life_cycle
--exec $UTIL/log.sh im_daemon_life_cycle Waiting for IM-main to start accepting connections...
--exec $UTIL/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 55 im_daemon_life_cycle
--exec $UTIL/log.sh im_daemon_life_cycle Main-test: done.
###########################################################################
#
# BUG#12751: Instance Manager: client hangs
# - start nonguarded instance (mysqld2);
# - kill IM-main and get it restarted by IM-angel;
# - check that guarded instance (mysqld1) is accepting connections.
# - check that non-guarded instance (mysqld2) were not stopped.
#
###########################################################################
--echo
--echo --------------------------------------------------------------------
--echo -- Test for BUG#12751
--echo --------------------------------------------------------------------
--exec $UTIL/log.sh im_daemon_life_cycle BUG12751: starting...
# 1. Start mysqld;
--exec $UTIL/log.sh im_daemon_life_cycle mysqld2: starting...
START INSTANCE mysqld2;
--exec $UTIL/log.sh im_daemon_life_cycle mysqld2: waiting to start...
--exec $UTIL/wait_for_process.sh $IM_MYSQLD2_PATH_PID 55 started im_daemon_life_cycle
--exec $UTIL/log.sh im_daemon_life_cycle mysqld2: started.
# 2. Restart IM-main;
--exec $UTIL/log.sh im_daemon_life_cycle Killing IM-main...
--exec $UTIL/kill_n_check.sh $IM_PATH_PID restarted 55 im_daemon_life_cycle
--exec $UTIL/log.sh im_daemon_life_cycle Waiting for IM-main to start accepting connections...
--exec $UTIL/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 55 im_daemon_life_cycle
# 3. Issue some statement -- connection should be re-established.
--exec $UTIL/log.sh im_daemon_life_cycle Checking that IM-main processing commands...
--replace_column 2 STATE 3 VERSION_NUMBER 4 VERSION
SHOW INSTANCE STATUS mysqld1;
# 4. Stop mysqld2, because it will not be stopped by IM, as it is nonguarded.
# So, if it we do not stop it, it will be stopped by mysql-test-run.pl with
# warning.
--exec $UTIL/log.sh im_daemon_life_cycle mysqld2: stopping...
STOP INSTANCE mysqld2;
--exec $UTIL/log.sh im_daemon_life_cycle mysqld2: waiting to stop...
--exec $UTIL/wait_for_process.sh $IM_MYSQLD2_PATH_PID 55 stopped im_daemon_life_cycle
--exec $UTIL/log.sh im_daemon_life_cycle mysqld2: stopped.
###########################################################################
--exec $UTIL/log.sh im_daemon_life_cycle BUG12751: done.
###########################################################################
#
# This test suite checks the following statements:
# - CREATE INSTANCE <instance_name> [option1[=option1_value], ...];
# - DROP INSTANCE <instance_name>;
#
# For CREATE INSTANCE we check that:
# - CREATE INSTANCE succeeds for non-existing instance;
# - CREATE INSTANCE fails for existing instance;
# - CREATE INSTANCE can get additional options with and w/o values;
# - CREATE INSTANCE parses options and handles grammar errors correctly.
# Check that strings with spaces are handled correctly, unknown (for
# mysqld) options should also be handled;
# - CREATE INSTANCE updates both config file and internal configuration cache;
# - CREATE INSTANCE allows to create instances only with properly formed
# names (mysqld*);
#
# For DROP INSTANCE we check that:
# - DROP INSTANCE succeeds for existing instance;
# - DROP INSTANCE fails for non-existing instance;
# - DROP INSTANCE fails for active instance.
# - DROP INSTANCE updates both config file and internal configuration cache;
#
# NOTE: each CREATE INSTANCE statement must specify socket-file-name, otherwise
# this results of the test can be affected by another running test suite.
#
###########################################################################
--source suite/im/t/im_check_env.inc
###########################################################################
#
# Check starting conditions.
#
###########################################################################
# Check that the configuration file contains only instances that we expect.
--echo --------------------------------------------------------------------
--exec grep '^server_id[^a-zA-Z0-9_\-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
###########################################################################
#
# CREATE INSTANCE tests.
#
###########################################################################
# Check that CREATE INSTANCE succeeds for non-existing instance and also check
# that both config file and internal configuration cache have been updated.
CREATE INSTANCE mysqld3
server_id = 3,
socket = "$MYSQL_TMP_DIR/mysqld_3.sock";
SHOW INSTANCES;
--echo --------------------------------------------------------------------
--exec grep '^server_id[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
# Check that CREATE INSTANCE fails for existing instance. Let's all three
# existing instances (running one, stopped one and just created one). Just in
# case...
--error 3012 # ER_CREATE_EXISTING_INSTANCE
CREATE INSTANCE mysqld1;
--error 3012 # ER_CREATE_EXISTING_INSTANCE
CREATE INSTANCE mysqld2;
--error 3012 # ER_CREATE_EXISTING_INSTANCE
CREATE INSTANCE mysqld3;
# Check that CREATE INSTANCE can get additional options with and w/o values.
# Ensure that config file is updated properly.
# - without values;
--echo --------------------------------------------------------------------
--exec grep "^nonguarded\$" $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
CREATE INSTANCE mysqld4
nonguarded,
server_id = 4,
socket = "$MYSQL_TMP_DIR/mysqld_4.sock";
SHOW INSTANCES;
--echo --------------------------------------------------------------------
--exec grep "^nonguarded\$" $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
# - with value;
--echo --------------------------------------------------------------------
--exec grep '^test-A[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^test-B[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
CREATE INSTANCE mysqld5
test-A = 000,
test-B = test,
server_id = 5,
socket = "$MYSQL_TMP_DIR/mysqld_5.sock";
SHOW INSTANCES;
--echo --------------------------------------------------------------------
--exec grep '^test-A[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
--exec grep '^test-B[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
# Check that CREATE INSTANCE parses options and handles grammar errors
# correctly. Check that strings with spaces are handled correctly,
# unknown (for mysqld) options should also be handled.
# - check handling of extra spaces;
--echo --------------------------------------------------------------------
--exec grep '^test-C1[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^test-C2[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
CREATE INSTANCE mysqld6
test-C1 = 10 ,
test-C2 = 02 ,
server_id = 6,
socket = "$MYSQL_TMP_DIR/mysqld_6.sock";
SHOW INSTANCES;
--echo --------------------------------------------------------------------
--exec grep '^test-C1[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
--exec grep '^test-C2[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
# - check handling of grammar error;
--echo --------------------------------------------------------------------
--exec grep '^test-D[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^test-E[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--error ER_SYNTAX_ERROR
CREATE INSTANCE mysqld7 test-D = test-D-value ;
SHOW INSTANCES;
--error ER_SYNTAX_ERROR
CREATE INSTANCE mysqld8 test-E 0 ;
SHOW INSTANCES;
--error ER_SYNTAX_ERROR
CREATE INSTANCE mysqld8 test-F = ;
SHOW INSTANCES;
--echo --------------------------------------------------------------------
--exec grep '^test-D[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^test-E[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
# - check parsing of string option values
--echo --------------------------------------------------------------------
--exec grep '^test-1[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^test-2[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^test-3[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^test-4[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^test-5[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^test-6[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^test-7[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
CREATE INSTANCE mysqld9
test-1=" hello world ",
test-2=' ',
server_id = 9,
socket = "$MYSQL_TMP_DIR/mysqld_9.sock";
SHOW INSTANCES;
CREATE INSTANCE mysqld10
test-3='\b\babc\sdef',
server_id = 10,
socket = "$MYSQL_TMP_DIR/mysqld_10.sock";
# test-3='abc def'
SHOW INSTANCES;
CREATE INSTANCE mysqld11
test-4='abc\tdef',
test-5='abc\ndef',
server_id = 11,
socket = "$MYSQL_TMP_DIR/mysqld_11.sock";
SHOW INSTANCES;
CREATE INSTANCE mysqld12
test-6="abc\rdef",
test-7="abc\\def",
server_id = 12,
socket = "$MYSQL_TMP_DIR/mysqld_12.sock";
# test-6=abc
SHOW INSTANCES;
--error ER_SYNTAX_ERROR
CREATE INSTANCE mysqld13 test-bad=' \ ';
SHOW INSTANCES;
--echo --------------------------------------------------------------------
--exec grep '^test-1[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
--exec grep '^test-2[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
--exec grep '^test-3[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
--exec grep '^test-4[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
--exec grep '^test-5[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
--exec grep '^test-6[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
--exec grep '^test-7[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
--exec grep '^test-bad' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
# Check that CREATE INSTANCE allows to create instances only with properly
# formed names (mysqld*).
--error 3014 # ER_MALFORMED_INSTANCE_NAME
CREATE INSTANCE qqq1;
let $UTIL=$MYSQL_TEST_DIR/suite/im/t;
###########################################################################
#
# This file contains test for (1.1) test suite.
#
# Consult WL#2789 for more information.
#
###########################################################################
--source suite/im/t/im_check_env.inc
###########################################################################
#
# 1.1.2. Check 'START INSTANCE' command:
# - start the second instance;
# - check that it is reported as online;
# - execute some SQL-statement on mysqld2 to ensure that it is really up and
# running;
#
###########################################################################
--echo
--echo --------------------------------------------------------------------
--echo -- 1.1.2.
--echo --------------------------------------------------------------------
START INSTANCE mysqld2;
# FIXME: START INSTANCE should be synchronous.
--exec $UTIL/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started im_life_cycle
# FIXME: Result of SHOW INSTANCES here is not deterministic unless START
# INSTANCE is synchronous. Even waiting for mysqld to start by looking at
# its pid file is not enough, because it is unknown when IM detects that
# mysqld has started.
# SHOW INSTANCES;
--connect (mysql_con,localhost,root,,mysql,$IM_MYSQLD2_PORT,$IM_MYSQLD2_SOCK)
--connection mysql_con
--replace_result $IM_MYSQLD2_PORT IM_MYSQLD2_PORT
SHOW VARIABLES LIKE 'port';
--connection default
--disconnect mysql_con
###########################################################################
#
# 1.1.3. Check 'STOP INSTANCE' command:
# - stop the second instance;
# - check that it is reported as offline;
# - TODO: try to execute some SQL-statement to ensure that it is really down;
#
###########################################################################
--echo
--echo --------------------------------------------------------------------
--echo -- 1.1.3.
--echo --------------------------------------------------------------------
STOP INSTANCE mysqld2;
# FIXME: STOP INSTANCE should be synchronous.
--exec $UTIL/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 stopped im_life_cycle
# FIXME: Result of SHOW INSTANCES here is not deterministic unless START
# INSTANCE is synchronous. Even waiting for mysqld to start by looking at
# its pid file is not enough, because it is unknown when IM detects that
# mysqld has started.
# SHOW INSTANCES;
###########################################################################
#
# 1.1.4. Check that Instance Manager reports correct errors for 'START
# INSTANCE' command:
# - if the client tries to start unregistered instance;
# - if the client tries to start already started instance;
# - if the client submits invalid arguments;
#
###########################################################################
--echo
--echo --------------------------------------------------------------------
--echo -- 1.1.4.
--echo --------------------------------------------------------------------
--error 3000 # ER_BAD_INSTANCE_NAME
START INSTANCE mysqld3;
--error 3002 # ER_INSTANCE_ALREADY_STARTED
START INSTANCE mysqld1;
###########################################################################
#
# 1.1.5. Check that Instance Manager reports correct errors for
# 'STOP INSTANCE' command:
# - if the client tries to start unregistered instance;
# - if the client tries to start already stopped instance;
# - if the client submits invalid arguments;
#
###########################################################################
--echo
--echo --------------------------------------------------------------------
--echo -- 1.1.5.
--echo --------------------------------------------------------------------
--error 3000 # ER_BAD_INSTANCE_NAME
STOP INSTANCE mysqld3;
# TODO: IM should be fixed.
# BUG#12673: Instance Manager allows to stop the instance many times
# --error 3002 # ER_INSTANCE_ALREADY_STARTED
# STOP INSTANCE mysqld2;
###########################################################################
#
# 1.1.6. Check that Instance Manager is able to restart guarded instances.
#
###########################################################################
--echo
--echo --------------------------------------------------------------------
--echo -- 1.1.6.
--echo --------------------------------------------------------------------
--exec $UTIL/kill_n_check.sh $IM_MYSQLD1_PATH_PID restarted 30 im_life_cycle
# Give some time to IM to detect that mysqld was restarted. It should be
# longer than monitoring interval.
--sleep 3
SHOW INSTANCES;
###########################################################################
#
# 1.1.7. Check that Instance Manager does not restart non-guarded instance.
#
###########################################################################
--echo
--echo --------------------------------------------------------------------
--echo -- 1.1.7.
--echo --------------------------------------------------------------------
START INSTANCE mysqld2;
# FIXME: START INSTANCE should be synchronous.
--exec $UTIL/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started im_life_cycle
# FIXME: Result of SHOW INSTANCES here is not deterministic unless START
# INSTANCE is synchronous. Even waiting for mysqld to start by looking at
# its pid file is not enough, because it is unknown when IM detects that
# mysqld has started.
# SHOW INSTANCES;
--exec $UTIL/kill_n_check.sh $IM_MYSQLD2_PATH_PID killed 10 im_life_cycle
# FIXME: Result of SHOW INSTANCES here is not deterministic unless START
# INSTANCE is synchronous. Even waiting for mysqld to start by looking at
# its pid file is not enough, because it is unknown when IM detects that
# mysqld has started.
# SHOW INSTANCES;
###########################################################################
#
# 1.1.8. Check that Instance Manager returns an error on
# incomplete SHOW INSTANCE STATUS command.
#
###########################################################################
--echo
--echo --------------------------------------------------------------------
--echo -- 1.1.8.
--echo --------------------------------------------------------------------
--error ER_SYNTAX_ERROR
SHOW INSTANCE STATUS;
#
# Tests for bug fixes
#
#
# Bug #12813 Instance Manager: START/STOP INSTANCE commands accept
# a list as argument.
#
--echo
--echo --------------------------------------------------------------------
--echo -- BUG#12813
--echo --------------------------------------------------------------------
--error ER_SYNTAX_ERROR
START INSTANCE mysqld1,mysqld2,mysqld3;
--error ER_SYNTAX_ERROR
STOP INSTANCE mysqld1,mysqld2,mysqld3;
#
# Bug #12673: Instance Manager: allows to stop the instance many times
#
--error 3001
STOP INSTANCE mysqld2;
--echo End of 5.0 tests
###########################################################################
#
# This test suite checks the following statements:
# - SET <instance id>.<option name> = <option value>;
# - UNSET <instance id>.<option name> = <option value>;
# - FLUSH INSTANCES;
#
# For SET/UNSET we check that:
# - SET ignores spaces correctly;
# - UNSET does not allow option-value part (= <option value>);
# - SET/UNSET can be applied several times w/o error;
# - SET/UNSET is allowed only for stopped instances;
# - SET/UNSET updates both the configuration cache in IM and
# the configuration file;
#
# For FLUSH INSTANCES we check that:
# - FLUSH INSTANCES is allowed only when all instances are stopped;
#
# According to the IM implementation details, we should play at least with the
# following options:
# - server_id
# - port
# - nonguarded
#
# Let's test SET statement on the option 'server_id'. It's expected that
# originally the instances have the following server ids and states:
# - mysqld1: server_id: 1; running (online)
# - mysqld2: server_id: 2; stopped (offline)
#
# NOTE: each CREATE INSTANCE statement must specify socket-file-name, otherwise
# this results of the test can be affected by another running test suite.
#
###########################################################################
--source suite/im/t/im_check_env.inc
###########################################################################
#
# Check that SET/UNSET is allowed only for stopped instances.
#
###########################################################################
# - check that SET/UNSET is denied for running instances;
--error 3015 # ER_INSTANCE_IS_ACTIVE
UNSET mysqld1.server_id;
--error 3015 # ER_INSTANCE_IS_ACTIVE
SET mysqld1.server_id = 11;
# - check that SET/UNSET is denied for active instances:
# - create dummy misconfigured instance;
# - start it;
# - try to set/unset options;
CREATE INSTANCE mysqld3
datadir = '/',
server_id = 3,
socket = "$MYSQL_TMP_DIR/mysqld_3.sock";
START INSTANCE mysqld3;
# FIXME: START INSTANCE should be synchronous.
--sleep 3
# should be longer than monitoring interval and enough to start instance.
# NOTE: We can not analyze state of the instance here -- it can be Failed or
# Starting because Instance Manager is trying to start the misconfigured
# instance several times.
--error 3015 # ER_INSTANCE_IS_ACTIVE
UNSET mysqld3.server_id;
--error 3015 # ER_INSTANCE_IS_ACTIVE
SET mysqld3.server_id = 11;
STOP INSTANCE mysqld3;
# FIXME: STOP INSTANCE should be synchronous.
--sleep 3
# should be longer than monitoring interval and enough to stop instance.
--replace_column 3 VERSION_NUMBER 4 VERSION
SHOW INSTANCE STATUS mysqld3;
# - check that SET/UNSET succeed for stopped instances;
# - check that SET/UNSET can be applied multiple times;
UNSET mysqld2.server_id;
UNSET mysqld2.server_id;
--replace_column 2 option_value
SHOW INSTANCE OPTIONS mysqld2;
SET mysqld2.server_id = 2;
SET mysqld2.server_id = 2;
--replace_column 2 option_value
SHOW INSTANCE OPTIONS mysqld2;
# - check that UNSET does not allow option-value part (= <option value>);
--error ER_SYNTAX_ERROR
UNSET mysqld2.server_id = 11;
# - check that SET/UNSET working properly with multiple options;
SET mysqld2.aaa, mysqld3.bbb, mysqld2.ccc = 0010, mysqld3.ddd = 0020;
--echo --------------------------------------------------------------------
--exec grep "^aaa\$" $MYSQLTEST_VARDIR/im.cnf ;
--echo --------------------------------------------------------------------
--exec grep "^bbb\$" $MYSQLTEST_VARDIR/im.cnf ;
--echo --------------------------------------------------------------------
--exec grep '^ccc[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf ;
--echo --------------------------------------------------------------------
--exec grep '^ddd[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf ;
--echo --------------------------------------------------------------------
UNSET mysqld2.aaa, mysqld3.bbb, mysqld2.ccc, mysqld3.ddd;
--echo --------------------------------------------------------------------
--exec grep "^aaa\$" $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep "^bbb\$" $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^ccc[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^ddd[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
# - check that if some instance name is invalid or the active is active,
# whole SET-statement will not be executed;
--error 3000 # ER_BAD_INSTANCE_NAME
SET mysqld2.aaa, mysqld3.bbb, mysqld.ccc = 0010;
--echo --------------------------------------------------------------------
--exec grep "^aaa\$" $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep "^bbb\$" $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^ccc[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--error 3015 # ER_INSTANCE_IS_ACTIVE
SET mysqld2.aaa, mysqld3.bbb, mysqld1.ccc = 0010;
--echo --------------------------------------------------------------------
--exec grep "^aaa\$" $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep "^bbb\$" $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep '^ccc[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
# - check that if some instance name is invalid or the active is active,
# whole UNSET-statement will not be executed;
--error 3000 # ER_BAD_INSTANCE_NAME
UNSET mysqld2.server_id, mysqld3.server_id, mysqld.ccc;
--echo --------------------------------------------------------------------
--exec grep '^server_id[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
--error 3015 # ER_INSTANCE_IS_ACTIVE
UNSET mysqld2.server_id, mysqld3.server_id, mysqld1.ccc;
--echo --------------------------------------------------------------------
--exec grep '^server_id[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf;
--echo --------------------------------------------------------------------
DROP INSTANCE mysqld3;
# - check that spaces are handled correctly;
SET mysqld2.server_id=222;
SET mysqld2.server_id = 222;
SET mysqld2.server_id = 222 ;
SET mysqld2 . server_id = 222 ;
SET mysqld2 . server_id = 222 , mysqld2 . aaa , mysqld2 . bbb ;
--echo --------------------------------------------------------------------
--exec grep '^server_id[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf ;
--echo --------------------------------------------------------------------
--exec grep "^aaa\$" $MYSQLTEST_VARDIR/im.cnf ;
--echo --------------------------------------------------------------------
--exec grep "^bbb\$" $MYSQLTEST_VARDIR/im.cnf ;
--echo --------------------------------------------------------------------
UNSET mysqld2 . aaa , mysqld2 . bbb ;
--echo --------------------------------------------------------------------
--exec grep '^server_id[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf ;
--echo --------------------------------------------------------------------
--exec grep "^aaa\$" $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
--exec grep "^bbb\$" $MYSQLTEST_VARDIR/im.cnf || true;
--echo --------------------------------------------------------------------
###########################################################################
#
# Check that SET/UNSET updates both the configuration cache in IM and
# the configuration file.
#
###########################################################################
# - check that the configuration file has been updated (i.e. contains
# server_id=SERVER_ID for mysqld2);
--echo --------------------------------------------------------------------
--exec grep '^server_id[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf ;
--echo --------------------------------------------------------------------
# - (for mysqld1) check that the running instance has not been affected:
# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
# returns zero;
--connection mysql1_con
SHOW VARIABLES LIKE 'server_id';
--connection default
# - check that internal cache of Instance Manager has been affected;
# TODO: we should check only server_id option here.
# SHOW INSTANCE OPTIONS mysqld2;
###########################################################################
#
# Check that FLUSH INSTANCES is allowed only when all instances are stopped.
#
###########################################################################
SHOW INSTANCES;
--error 3016 # ER_THERE_IS_ACTIVE_INSTACE
FLUSH INSTANCES;
STOP INSTANCE mysqld1;
# FIXME: STOP INSTANCE should be synchronous.
--sleep 3
# should be longer than monitoring interval and enough to stop instance.
SHOW INSTANCES;
FLUSH INSTANCES;
###########################################################################
#
# This file contains test for (2) test suite.
#
# Consult WL#2789 for more information.
#
###########################################################################
--source suite/im/t/im_check_env.inc
let $UTIL=$MYSQL_TEST_DIR/suite/im/t;
###########################################################################
#
# Check 'SHOW INSTANCE OPTIONS' command.
#
# Since configuration of an mysqld-instance contains directories, we should
# completely ignore the second column (values) in order to make the test
# case produce the same results on different installations;
# TODO: ignore values of only directory-specific options.
#
--replace_column 2 VALUE
SHOW INSTANCE OPTIONS mysqld1;
--replace_column 2 VALUE
SHOW INSTANCE OPTIONS mysqld2;
#
# Before checking log files, we should start the second instance (mysqld2) to
# give it a chance to create log files.
#
START INSTANCE mysqld2;
--exec $UTIL/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started im_utils
STOP INSTANCE mysqld2;
--exec $UTIL/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 stopped im_utils
#
# Check 'SHOW LOG FILES' command:
# - check that log files of both offline and online instances are accessible;
# - since placement of the log files is installation-specific, we should
# ignore it in comparisson;
# - also, we should ignore log file size, since it may depend on the version
# being tested;
#
--replace_column 2 PATH 3 FILE_SIZE
SHOW mysqld1 LOG FILES;
--replace_column 2 PATH 3 FILE_SIZE
SHOW mysqld2 LOG FILES;
#
# Check 'SHOW LOG' command:
# - check that all three kinds of logs are available for both offline and
# online instances;
# - we should ignore the value, because it is very specific and depends on
# many factors; we only check that Instance Manager is able to provide log
# files.
#
# mysqld1 (online) w/o the optional argument.
--replace_column 1 LOG_DATA
SHOW mysqld1 LOG ERROR 10;
--replace_column 1 LOG_DATA
SHOW mysqld1 LOG SLOW 10;
--replace_column 1 LOG_DATA
SHOW mysqld1 LOG GENERAL 10;
# mysqld1 (online) with the optional argument.
--replace_column 1 LOG_DATA
SHOW mysqld1 LOG ERROR 10, 2;
--replace_column 1 LOG_DATA
SHOW mysqld1 LOG SLOW 10, 2;
--replace_column 1 LOG_DATA
SHOW mysqld1 LOG GENERAL 10, 2;
# mysqld2 (offline) w/o the optional argument.
--replace_column 1 LOG_DATA
SHOW mysqld2 LOG ERROR 10;
--replace_column 1 LOG_DATA
SHOW mysqld2 LOG SLOW 10;
--replace_column 1 LOG_DATA
SHOW mysqld2 LOG GENERAL 10;
# mysqld2 (offline) with the optional argument.
--replace_column 1 LOG_DATA
SHOW mysqld2 LOG ERROR 10, 2;
--replace_column 1 LOG_DATA
SHOW mysqld2 LOG SLOW 10, 2;
--replace_column 1 LOG_DATA
SHOW mysqld2 LOG GENERAL 10, 2;
#!/bin/sh
###########################################################################
# NOTE: this script returns 0 (success) even in case of failure (except for
# usage-error). This is because this script is executed under
# mysql-test-run[.pl] and it's better to examine particular problem in log
# file, than just having said that the test case has failed.
###########################################################################
basename=`basename "$0"`
dirname=`dirname "$0"`
###########################################################################
. "$dirname/utils.sh"
###########################################################################
check_restart()
{
if [ ! -r "$pid_path" ]; then
log_debug "No '$pid_path' found."
user_msg='the process was killed'
return 1
fi
new_pid=`cat "$pid_path" 2>/dev/null`
err_code=$?
log_debug "err_code: $err_code; original_pid: $original_pid; new_pid: $new_pid."
if [ $err_code -eq 0 -a "$original_pid" = "$new_pid" ]; then
log_debug "The process was not restarted."
user_msg='the process was not restarted'
return 1
fi
log_debug "The process was restarted."
user_msg='the process was restarted'
return 0
}
###########################################################################
if [ $# -ne 4 ]; then
echo "Usage: $basename <pid file path> killed|restarted <timeout> <test id>"
exit 1
fi
pid_path="$1"
expected_result="$2"
total_timeout="$3"
test_id="$4"
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
log_debug "-- $basename: starting --"
log_debug "pid_path: '$pid_path'"
log_debug "expected_result: '$expected_result'"
log_debug "total_timeout: '$total_timeout'"
log_debug "test_id: '$test_id'"
log_debug "log_file: '$log_file'"
###########################################################################
if [ "$expected_result" != 'killed' -a \
"$expected_result" != 'restarted' ]; then
log_error "Invalid second argument ($expected_result): 'killed' or 'restarted' expected."
quit 0
fi
if [ -z "$pid_path" ]; then
log_error "Invalid PID path ($pid_path)."
quit 0
fi
if [ ! -r "$pid_path" ]; then
log_error "PID file ($pid_path) does not exist."
quit 0
fi
if [ -z "$total_timeout" ]; then
log_error "Timeout is not specified."
quit 0
fi
###########################################################################
original_pid=`cat "$pid_path"`
log_debug "original_pid: $original_pid."
log_info "Killing the process..."
kill -9 $original_pid
###########################################################################
log_info "Waiting..."
if [ "$expected_result" = "restarted" ]; then
# Wait for the process to restart.
cur_attempt=1
while true; do
log_debug "cur_attempt: $cur_attempt."
if check_restart; then
log_info "Success: $user_msg."
quit 0
fi
[ $cur_attempt -ge $total_timeout ] && break
log_debug "Sleeping for 1 second..."
sleep 1
cur_attempt=`expr $cur_attempt + 1`
done
log_error "$user_msg."
quit 0
else # $expected_result == killed
# Here we have to sleep for some long time to ensure that the process will
# not be restarted.
log_debug "Sleeping for $total_timeout seconds..."
sleep $total_timeout
new_pid=`cat "$pid_path" 2>/dev/null`
log_debug "new_pid: $new_pid."
if [ "$new_pid" -a "$new_pid" -ne "$original_pid" ]; then
log_error "The process was restarted."
else
log_info "Success: the process was killed."
fi
quit 0
fi
#!/bin/sh
###########################################################################
basename=`basename "$0"`
dirname=`dirname "$0"`
###########################################################################
. "$dirname/utils.sh"
###########################################################################
if [ $# -lt 2 ]; then
echo "Usage: $basename <test id> log message ..."
exit 1
fi
test_id="$1"
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
shift
log_debug "$*"
###########################################################################
#
# This file provides utility functions and is included by other scripts.
#
# The following global variables must be set before calling functions from this
# file:
# - basename -- base name of the calling script (main application);
# - log_file -- where to store log records;
#
###########################################################################
log()
{
[ -z "$log_file" ] && return;
log_level="$1"
log_msg="$2"
ts=`date`
echo "[$ts] [$basename] [$log_level] $log_msg" >> "$log_file";
}
###########################################################################
log_debug()
{
log 'DEBUG' "$1"
}
###########################################################################
log_info()
{
log 'INFO' "$1"
echo "$1"
}
###########################################################################
log_error()
{
log 'ERROR' "$1"
echo "Error: $1"
}
###########################################################################
quit()
{
exit_status="$1"
log_debug "-- $basename: finished (exit_status: $exit_status) --"
exit $exit_status
}
#!/bin/sh
###########################################################################
# NOTE: this script returns 0 (success) even in case of failure (except for
# usage-error). This is because this script is executed under
# mysql-test-run[.pl] and it's better to examine particular problem in log
# file, than just having said that the test case has failed.
###########################################################################
basename=`basename "$0"`
dirname=`dirname "$0"`
###########################################################################
. "$dirname/utils.sh"
###########################################################################
check_started()
{
if [ ! -r "$pid_path" ]; then
log_debug "No PID-file ($pid_path) found -- not started."
return 1
fi
new_pid=`cat "$pid_path" 2>/dev/null`
err_code=$?
log_debug "err_code: $err_code; new_pid: $new_pid."
if [ $? -ne 0 -o -z "$new_pid" ]; then
log_debug "The process was not started."
return 1
fi
log_debug "The process was started."
return 0
}
###########################################################################
check_stopped()
{
if [ -r "$pid_path" ]; then
log_debug "PID-file '$pid_path' exists -- not stopped."
return 1
fi
log_debug "No PID-file ($pid_path) found -- stopped."
return 0
}
###########################################################################
if [ $# -ne 4 ]; then
echo "Usage: $basename <pid file path> <total attempts> started|stopped <test id>"
exit 1
fi
pid_path="$1"
total_attempts="$2"
event="$3"
test_id="$4"
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
log_debug "-- $basename: starting --"
log_debug "pid_path: '$pid_path'"
log_debug "total_attempts: '$total_attempts'"
log_debug "event: '$event'"
log_debug "test_id: '$test_id'"
log_debug "log_file: '$log_file'"
###########################################################################
case "$event" in
started)
check_fn='check_started';
;;
stopped)
check_fn='check_stopped';
;;
*)
log_error "Invalid third argument ('started' or 'stopped' expected)."
quit 0
esac
###########################################################################
cur_attempt=1
while true; do
log_debug "cur_attempt: $cur_attempt."
if ( eval $check_fn ); then
log_info "Success: the process has been $event."
quit 0
fi
[ $cur_attempt -ge $total_attempts ] && break
log_debug "Sleeping for 1 second..."
sleep 1
cur_attempt=`expr $cur_attempt + 1`
done
log_error "The process has not been $event in $total_attempts secs."
quit 0
#!/bin/sh
###########################################################################
# NOTE: this script returns 0 (success) even in case of failure (except for
# usage-error). This is because this script is executed under
# mysql-test-run[.pl] and it's better to examine particular problem in log
# file, than just having said that the test case has failed.
###########################################################################
basename=`basename "$0"`
dirname=`dirname "$0"`
###########################################################################
. "$dirname/utils.sh"
###########################################################################
if [ $# -ne 7 ]; then
echo "Usage: wait_for_socket.sh <executable path> <socket path> <username> <password> <db> <timeout> <test id>"
exit 1
fi
client_exe="$1"
socket_path="$2"
username="$3"
password="$4"
db="$5"
total_timeout="$6"
test_id="$7"
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
log_debug "-- $basename: starting --"
log_debug "client_exe: '$client_exe'"
log_debug "socket_path: '$socket_path'"
log_debug "username: '$username'"
log_debug "password: '$password'"
log_debug "db: '$db'"
log_debug "total_timeout: '$total_timeout'"
log_debug "test_id: '$test_id'"
log_debug "log_file: '$log_file'"
###########################################################################
if [ -z "$client_exe" ]; then
log_error "Invalid path to client executable ($client_exe)."
quit 0;
fi
if [ ! -x "$client_exe" ]; then
log_error "Client by path '$client_exe' is not available."
quit 0;
fi
if [ -z "$socket_path" ]; then
log_error "Invalid socket patch ($socket_path)."
quit 0
fi
###########################################################################
client_args="--no-defaults --silent --socket=$socket_path --connect_timeout=1 "
[ -n "$username" ] && client_args="$client_args --user=$username "
[ -n "$password" ] && client_args="$client_args --password=$password "
[ -n "$db" ] && client_args="$client_args $db"
log_debug "client_args: '$client_args'"
###########################################################################
cur_attempt=1
while true; do
log_debug "cur_attempt: $cur_attempt."
if ( echo 'quit' | "$client_exe" $client_args >/dev/null 2>&1 ); then
log_info "Success: server is ready to accept connection on socket."
quit 0
fi
[ $cur_attempt -ge $total_timeout ] && break
sleep 1
cur_attempt=`expr $cur_attempt + 1`
done
log_error "Server does not accept connections after $total_timeout seconds."
quit 0
......@@ -22,6 +22,5 @@ base_configs=" \
--enable-local-infile \
--with-extra-charsets=all \
--prefix=N:/mysql \
--without-mysqlmanager \
--without-man \
"
# Copyright (C) 2006 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
ADD_DEFINITIONS(-DMYSQL_SERVER -DMYSQL_INSTANCE_MANAGER)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/sql
${PROJECT_SOURCE_DIR}/extra/yassl/include)
ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instance.cc instance_map.cc
instance_options.cc listener.cc log.cc manager.cc messages.cc mysql_connection.cc
mysqlmanager.cc options.cc parse.cc parse_output.cc priv.cc protocol.cc
thread_registry.cc user_map.cc imservice.cpp windowsservice.cpp
user_management_commands.cc
../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
../../libmysql/errmsg.c)
ADD_DEPENDENCIES(mysqlmanager GenError)
TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32)
# Copyright (C) 2003, 2006 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
SUBDIRS = . instance-manager
DIST_SUBDIRS = . instance-manager
# Don't update the files from bitkeeper
%::SCCS/s.%
# Copyright (C) 2006 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
ADD_DEFINITIONS(-DMYSQL_SERVER -DMYSQL_INSTANCE_MANAGER)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/sql
${PROJECT_SOURCE_DIR}/extra/yassl/include)
ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instance.cc instance_map.cc
instance_options.cc listener.cc log.cc manager.cc messages.cc mysql_connection.cc
mysqlmanager.cc options.cc parse.cc parse_output.cc priv.cc protocol.cc
thread_registry.cc user_map.cc IMService.cpp WindowsService.cpp
user_management_commands.cc
../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
../../libmysql/errmsg.c)
ADD_DEPENDENCIES(mysqlmanager GenError)
TARGET_LINK_LIBRARIES(mysqlmanager debug dbug mysys strings taocrypt vio yassl zlib wsock32)
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("mysqlmanager" "asInvoker")
ENDIF(EMBED_MANIFESTS)
/* Copyright (C) 2005 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <winsock2.h>
#include <signal.h>
#include "IMService.h"
#include "log.h"
#include "manager.h"
#include "options.h"
static const char * const IM_SVC_USERNAME= NULL;
static const char * const IM_SVC_PASSWORD= NULL;
IMService::IMService(void)
:WindowsService("MySqlManager", "MySQL Manager")
{
}
IMService::~IMService(void)
{
}
void IMService::Stop()
{
ReportStatus(SERVICE_STOP_PENDING);
/* stop the IM work */
raise(SIGTERM);
}
void IMService::Run(DWORD argc, LPTSTR *argv)
{
/* report to the SCM that we're about to start */
ReportStatus((DWORD)SERVICE_START_PENDING);
Options::load(argc, argv);
/* init goes here */
ReportStatus((DWORD)SERVICE_RUNNING);
/* wait for main loop to terminate */
(void) Manager::main();
Options::cleanup();
}
void IMService::Log(const char *msg)
{
log_info(msg);
}
int IMService::main()
{
IMService winService;
if (Options::Service::install_as_service)
{
if (winService.IsInstalled())
{
log_info("Service is already installed.");
return 1;
}
if (winService.Install(IM_SVC_USERNAME, IM_SVC_PASSWORD))
{
log_info("Service installed successfully.");
return 0;
}
else
{
log_error("Service failed to install.");
return 1;
}
}
if (Options::Service::remove_service)
{
if (!winService.IsInstalled())
{
log_info("Service is not installed.");
return 1;
}
if (winService.Remove())
{
log_info("Service removed successfully.");
return 0;
}
else
{
log_error("Service failed to remove.");
return 1;
}
}
log_info("Initializing Instance Manager service...");
if (!winService.Init())
{
log_error("Service failed to initialize.");
fprintf(stderr,
"The service should be started by Windows Service Manager.\n"
"The MySQL Manager should be started with '--standalone'\n"
"to run from command line.");
return 1;
}
return 0;
}
/* Copyright (C) 2005 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#pragma once
#include "WindowsService.h"
class IMService: public WindowsService
{
public:
static int main();
private:
IMService(void);
~IMService(void);
protected:
void Log(const char *msg);
void Stop();
void Run(DWORD argc, LPTSTR *argv);
};
# Copyright (C) 2004 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
INCLUDES= @ZLIB_INCLUDES@ -I$(top_srcdir)/include \
@openssl_includes@ -I$(top_builddir)/include
DEFS= -DMYSQL_INSTANCE_MANAGER -DMYSQL_SERVER
# As all autoconf variables depend from ${prefix} and being resolved only when
# make is run, we can not put these defines to a header file (e.g. to
# default_options.h, generated from default_options.h.in)
# See automake/autoconf docs for details
noinst_LTLIBRARIES= liboptions.la
noinst_LIBRARIES= libnet.a
liboptions_la_CXXFLAGS= $(CXXFLAGS) \
-DDEFAULT_PID_FILE_NAME="$(localstatedir)/mysqlmanager.pid" \
-DDEFAULT_LOG_FILE_NAME="$(localstatedir)/mysqlmanager.log" \
-DDEFAULT_SOCKET_FILE_NAME="/tmp/mysqlmanager.sock" \
-DDEFAULT_PASSWORD_FILE_NAME="/etc/mysqlmanager.passwd" \
-DDEFAULT_MYSQLD_PATH="$(libexecdir)/mysqld$(EXEEXT)" \
-DDEFAULT_CONFIG_FILE="my.cnf" \
-DPROTOCOL_VERSION=@PROTOCOL_VERSION@
liboptions_la_SOURCES= options.h options.cc priv.h priv.cc
liboptions_la_LIBADD= $(top_builddir)/libmysql/get_password.lo
# MySQL sometimes uses symlinks to reuse code
# All symlinked files are grouped in libnet.a
nodist_libnet_a_SOURCES= net_serv.cc client_settings.h
libnet_a_LIBADD= $(top_builddir)/sql/password.$(OBJEXT) \
$(top_builddir)/sql/pack.$(OBJEXT) \
$(top_builddir)/sql/sql_state.$(OBJEXT) \
$(top_builddir)/sql/mini_client_errors.$(OBJEXT)\
$(top_builddir)/sql/client.$(OBJEXT)
CLEANFILES= net_serv.cc client_settings.h
net_serv.cc:
rm -f net_serv.cc
@LN_CP_F@ $(top_srcdir)/sql/net_serv.cc net_serv.cc
client_settings.h:
rm -f client_settings.h
@LN_CP_F@ $(top_srcdir)/sql/client_settings.h client_settings.h
libexec_PROGRAMS= mysqlmanager
mysqlmanager_CXXFLAGS=
mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \
manager.h manager.cc log.h log.cc \
thread_registry.h thread_registry.cc \
listener.h listener.cc protocol.h protocol.cc \
mysql_connection.h mysql_connection.cc \
user_map.h user_map.cc \
messages.h messages.cc \
commands.h commands.cc \
instance.h instance.cc \
instance_map.h instance_map.cc\
instance_options.h instance_options.cc \
buffer.h buffer.cc parse.cc parse.h \
guardian.cc guardian.h \
parse_output.cc parse_output.h \
mysql_manager_error.h \
portability.h \
exit_codes.h \
user_management_commands.h \
user_management_commands.cc \
angel.h \
angel.cc
mysqlmanager_LDADD= @CLIENT_EXTRA_LDFLAGS@ \
liboptions.la \
libnet.a \
$(top_builddir)/vio/libvio.a \
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/strings/libmystrings.a \
$(top_builddir)/dbug/libdbug.a \
@openssl_libs@ @yassl_libs@ @ZLIB_LIBS@
EXTRA_DIST = WindowsService.cpp WindowsService.h IMService.cpp \
IMService.h CMakeLists.txt
tags:
ctags -R *.h *.cc
# Don't update the files from bitkeeper
%::SCCS/s.%
Instance Manager - manage MySQL instances locally and remotely.
File description:
mysqlmanager.cc - entry point to the manager, main,
options.{h,cc} - handle startup options
manager.{h,cc} - manager process
mysql_connection.{h,cc} - handle one connection with mysql client.
See also instance manager architecture description in mysqlmanager.cc.
/* Copyright (C) 2005 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "my_global.h"
#include <windows.h>
#include "WindowsService.h"
static WindowsService *gService;
WindowsService::WindowsService(const char *p_serviceName,
const char *p_displayName) :
statusCheckpoint(0),
serviceName(p_serviceName),
displayName(p_displayName),
inited(FALSE),
dwAcceptedControls(SERVICE_ACCEPT_STOP),
debugging(FALSE)
{
DBUG_ASSERT(serviceName != NULL);
/* TODO: shouldn't we check displayName too (can it really be NULL)? */
/* WindowsService is assumed to be singleton. Let's assure this. */
DBUG_ASSERT(gService == NULL);
gService= this;
status.dwServiceType= SERVICE_WIN32_OWN_PROCESS;
status.dwServiceSpecificExitCode= 0;
}
WindowsService::~WindowsService(void)
{
}
BOOL WindowsService::Install(const char *username, const char *password)
{
bool ret_val= FALSE;
SC_HANDLE newService;
SC_HANDLE scm;
if (IsInstalled())
return TRUE;
// determine the name of the currently executing file
char szFilePath[_MAX_PATH];
GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
// open a connection to the SCM
if (!(scm= OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
return FALSE;
newService= CreateService(scm, serviceName, displayName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, NULL, username,
password);
if (newService)
{
CloseServiceHandle(newService);
ret_val= TRUE;
}
CloseServiceHandle(scm);
return ret_val;
}
BOOL WindowsService::Init()
{
DBUG_ASSERT(serviceName != NULL);
if (inited)
return TRUE;
SERVICE_TABLE_ENTRY stb[] =
{
{ (LPSTR)serviceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
{ NULL, NULL }
};
inited= TRUE;
return StartServiceCtrlDispatcher(stb); //register with the Service Manager
}
BOOL WindowsService::Remove()
{
bool ret_val= FALSE;
if (!IsInstalled())
return TRUE;
// open a connection to the SCM
SC_HANDLE scm= OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
if (!scm)
return FALSE;
SC_HANDLE service= OpenService(scm, serviceName, DELETE);
if (service)
{
if (DeleteService(service))
ret_val= TRUE;
DWORD dw= ::GetLastError();
CloseServiceHandle(service);
}
CloseServiceHandle(scm);
return ret_val;
}
BOOL WindowsService::IsInstalled()
{
BOOL ret_val= FALSE;
SC_HANDLE scm= ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
SC_HANDLE serv_handle= ::OpenService(scm, serviceName, SERVICE_QUERY_STATUS);
ret_val= serv_handle != NULL;
::CloseServiceHandle(serv_handle);
::CloseServiceHandle(scm);
return ret_val;
}
void WindowsService::SetAcceptedControls(DWORD acceptedControls)
{
dwAcceptedControls= acceptedControls;
}
BOOL WindowsService::ReportStatus(DWORD currentState, DWORD waitHint,
DWORD dwError)
{
if (debugging)
return TRUE;
if(currentState == SERVICE_START_PENDING)
status.dwControlsAccepted= 0;
else
status.dwControlsAccepted= dwAcceptedControls;
status.dwCurrentState= currentState;
status.dwWin32ExitCode= dwError != 0 ?
ERROR_SERVICE_SPECIFIC_ERROR : NO_ERROR;
status.dwWaitHint= waitHint;
status.dwServiceSpecificExitCode= dwError;
if(currentState == SERVICE_RUNNING || currentState == SERVICE_STOPPED)
{
status.dwCheckPoint= 0;
statusCheckpoint= 0;
}
else
status.dwCheckPoint= ++statusCheckpoint;
// Report the status of the service to the service control manager.
BOOL result= SetServiceStatus(statusHandle, &status);
if (!result)
Log("ReportStatus failed");
return result;
}
void WindowsService::RegisterAndRun(DWORD argc, LPTSTR *argv)
{
statusHandle= ::RegisterServiceCtrlHandler(serviceName, ControlHandler);
if (statusHandle && ReportStatus(SERVICE_START_PENDING))
Run(argc, argv);
ReportStatus(SERVICE_STOPPED);
}
void WindowsService::HandleControlCode(DWORD opcode)
{
// Handle the requested control code.
switch(opcode) {
case SERVICE_CONTROL_STOP:
// Stop the service.
status.dwCurrentState= SERVICE_STOP_PENDING;
Stop();
break;
case SERVICE_CONTROL_PAUSE:
status.dwCurrentState= SERVICE_PAUSE_PENDING;
Pause();
break;
case SERVICE_CONTROL_CONTINUE:
status.dwCurrentState= SERVICE_CONTINUE_PENDING;
Continue();
break;
case SERVICE_CONTROL_SHUTDOWN:
Shutdown();
break;
case SERVICE_CONTROL_INTERROGATE:
ReportStatus(status.dwCurrentState);
break;
default:
// invalid control code
break;
}
}
void WINAPI WindowsService::ServiceMain(DWORD argc, LPTSTR *argv)
{
DBUG_ASSERT(gService != NULL);
// register our service control handler:
gService->RegisterAndRun(argc, argv);
}
void WINAPI WindowsService::ControlHandler(DWORD opcode)
{
DBUG_ASSERT(gService != NULL);
return gService->HandleControlCode(opcode);
}
/* Copyright (C) 2005 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#pragma once
class WindowsService
{
protected:
bool inited;
const char *serviceName;
const char *displayName;
SERVICE_STATUS_HANDLE statusHandle;
DWORD statusCheckpoint;
SERVICE_STATUS status;
DWORD dwAcceptedControls;
bool debugging;
public:
WindowsService(const char *p_serviceName, const char *p_displayName);
~WindowsService(void);
BOOL Install(const char *username, const char *password);
BOOL Remove();
BOOL Init();
BOOL IsInstalled();
void SetAcceptedControls(DWORD acceptedControls);
void Debug(bool debugFlag) { debugging= debugFlag; }
public:
static void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
static void WINAPI ControlHandler(DWORD CtrlType);
protected:
virtual void Run(DWORD argc, LPTSTR *argv)= 0;
virtual void Stop() {}
virtual void Shutdown() {}
virtual void Pause() {}
virtual void Continue() {}
virtual void Log(const char *msg) {}
BOOL ReportStatus(DWORD currentStatus, DWORD waitHint= 3000, DWORD dwError=0);
void HandleControlCode(DWORD opcode);
void RegisterAndRun(DWORD argc, LPTSTR *argv);
};
This diff is collapsed.
/* Copyright (C) 2003-2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef INCLUDES_MYSQL_ANGEL_H
#define INCLUDES_MYSQL_ANGEL_H
#ifndef __WIN__
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
#include <my_global.h>
class Angel
{
public:
static int main();
};
#endif // INCLUDES_MYSQL_ANGEL_H
#endif // __WIN__
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
#include "buffer.h"
#include <m_string.h>
const uint Buffer::BUFFER_INITIAL_SIZE= 4096;
const uint Buffer::MAX_BUFFER_SIZE= 16777216;
/*
Puts the given string to the buffer.
SYNOPSIS
append()
position start position in the buffer
string string to be put in the buffer
len_arg the length of the string. This way we can avoid some
strlens.
DESCRIPTION
The method puts a string into the buffer, starting from position .
In the case when the buffer is too small it reallocs the buffer. The
total size of the buffer is restricted with 16.
RETURN
0 - ok
1 - got an error in reserve()
*/
int Buffer::append(size_t position, const char *string, size_t len_arg)
{
if (reserve(position, len_arg))
return 1;
strnmov((char*) buffer + position, string, len_arg);
return 0;
}
/*
Checks whether the current buffer size is ok to put a string of the length
"len_arg" starting from "position" and reallocs it if no.
SYNOPSIS
reserve()
position the number starting byte on the buffer to store a buffer
len_arg the length of the string.
DESCRIPTION
The method checks whether it is possible to put a string of the "len_arg"
length into the buffer, starting from "position" byte. In the case when the
buffer is too small it reallocs the buffer. The total size of the buffer is
restricted with 16 Mb.
RETURN
0 - ok
1 - realloc error or we have come to the 16Mb barrier
*/
int Buffer::reserve(size_t position, size_t len_arg)
{
if (position + len_arg >= MAX_BUFFER_SIZE)
goto err;
if (position + len_arg >= buffer_size)
{
buffer= (uchar*) my_realloc(buffer,
min(MAX_BUFFER_SIZE,
max((uint) (buffer_size*1.5),
position + len_arg)), MYF(0));
if (!(buffer))
goto err;
buffer_size= (size_t) (buffer_size*1.5);
}
return 0;
err:
error= 1;
return 1;
}
int Buffer::get_size()
{
return (uint) buffer_size;
}
int Buffer::is_error()
{
return error;
}
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_BUFFER_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_BUFFER_H
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include <my_sys.h>
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
/*
This class is a simple implementation of the buffer of varying size.
It is used to store MySQL client-server protocol packets. This is why
the maximum buffer size if 16Mb. (See internals manual section
7. MySQL Client/Server Protocol)
*/
class Buffer
{
private:
static const uint BUFFER_INITIAL_SIZE;
/* maximum buffer size is 16Mb */
static const uint MAX_BUFFER_SIZE;
size_t buffer_size;
/* Error flag. Triggered if we get an error of some kind */
int error;
public:
Buffer(size_t buffer_size_arg= BUFFER_INITIAL_SIZE)
:buffer_size(buffer_size_arg), error(0)
{
/*
As append() will invokes realloc() anyway, it's ok if malloc returns 0
*/
if (!(buffer= (uchar*) my_malloc(buffer_size, MYF(0))))
buffer_size= 0;
}
~Buffer()
{
my_free(buffer, MYF(0));
}
public:
uchar *buffer;
int get_size();
int is_error();
int append(size_t position, const char *string, size_t len_arg);
int reserve(size_t position, size_t len_arg);
};
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_BUFFER_H */
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
#pragma implementation
#endif
#include "manager.h"
#include "command.h"
Command::Command()
:guardian(Manager::get_guardian()),
instance_map(Manager::get_instance_map())
{}
Command::~Command()
{}
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_COMMAND_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_COMMAND_H
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
/* Class responsible for allocation of IM commands. */
class Guardian;
class Instance_map;
struct st_net;
/*
Command - entry point for any command.
GangOf4: 'Command' design pattern
*/
class Command
{
public:
Command();
virtual ~Command();
/*
This operation incapsulates behaviour of the command.
SYNOPSIS
net The network connection to the client.
connection_id Client connection ID
RETURN
0 On success
non 0 On error. Client error code is returned.
*/
virtual int execute(st_net *net, ulong connection_id) = 0;
protected:
Guardian *guardian;
Instance_map *instance_map;
};
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_COMMAND_H */
This diff is collapsed.
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_COMMANDS_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_COMMANDS_H
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <hash.h>
#include "command.h"
#include "instance.h"
#include "parse.h"
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
/**
Print all instances of this instance manager.
Grammar: SHOW INSTANCES
*/
class Show_instances: public Command
{
public:
Show_instances()
{ }
public:
int execute(st_net *net, ulong connection_id);
private:
int write_header(st_net *net);
int write_data(st_net *net);
};
/**
Reread configuration file and refresh internal cache.
Grammar: FLUSH INSTANCES
*/
class Flush_instances: public Command
{
public:
Flush_instances()
{ }
public:
int execute(st_net *net, ulong connection_id);
};
/**
Base class for Instance-specific commands
(commands that operate on one instance).
Instance_cmd extends Command class by:
- an attribute for storing instance name;
- code to initialize instance name in constructor;
- an accessor to get instance name.
*/
class Instance_cmd : public Command
{
public:
Instance_cmd(const LEX_STRING *instance_name_arg);
protected:
inline const LEX_STRING *get_instance_name() const
{
return instance_name.get_str();
}
private:
Instance_name instance_name;
};
/**
Abstract class for Instance-specific commands.
Abstract_instance_cmd extends Instance_cmd by providing a common
framework for writing command-implementations. Basically, the class
implements Command::execute() pure virtual function in the following
way:
- Lock Instance_map;
- Get an instance by name. Return an error, if there is no such
instance;
- Lock the instance;
- Unlock Instance_map;
- Call execute_impl(), which should be implemented in derived class;
- Unlock the instance;
- Send response to the client and return error status.
*/
class Abstract_instance_cmd: public Instance_cmd
{
public:
Abstract_instance_cmd(const LEX_STRING *instance_name_arg);
public:
virtual int execute(st_net *net, ulong connection_id);
protected:
/**
This operation is intended to contain command-specific implementation.
MT-NOTE: this operation is called under acquired Instance's lock.
*/
virtual int execute_impl(st_net *net, Instance *instance) = 0;
/**
This operation is invoked on successful return of execute_impl() and is
intended to send closing data.
MT-NOTE: this operation is called under released Instance's lock.
*/
virtual int send_ok_response(st_net *net, ulong connection_id) = 0;
};
/**
Print status of an instance.
Grammar: SHOW INSTANCE STATUS <instance_name>
*/
class Show_instance_status: public Abstract_instance_cmd
{
public:
Show_instance_status(const LEX_STRING *instance_name_arg);
protected:
virtual int execute_impl(st_net *net, Instance *instance);
virtual int send_ok_response(st_net *net, ulong connection_id);
private:
int write_header(st_net *net);
int write_data(st_net *net, Instance *instance);
};
/**
Print options of chosen instance.
Grammar: SHOW INSTANCE OPTIONS <instance_name>
*/
class Show_instance_options: public Abstract_instance_cmd
{
public:
Show_instance_options(const LEX_STRING *instance_name_arg);
protected:
virtual int execute_impl(st_net *net, Instance *instance);
virtual int send_ok_response(st_net *net, ulong connection_id);
private:
int write_header(st_net *net);
int write_data(st_net *net, Instance *instance);
};
/**
Start an instance.
Grammar: START INSTANCE <instance_name>
*/
class Start_instance: public Abstract_instance_cmd
{
public:
Start_instance(const LEX_STRING *instance_name_arg);
protected:
virtual int execute_impl(st_net *net, Instance *instance);
virtual int send_ok_response(st_net *net, ulong connection_id);
};
/**
Stop an instance.
Grammar: STOP INSTANCE <instance_name>
*/
class Stop_instance: public Abstract_instance_cmd
{
public:
Stop_instance(const LEX_STRING *instance_name_arg);
protected:
virtual int execute_impl(st_net *net, Instance *instance);
virtual int send_ok_response(st_net *net, ulong connection_id);
};
/**
Create an instance.
Grammar: CREATE INSTANCE <instance_name> [<options>]
*/
class Create_instance: public Instance_cmd
{
public:
Create_instance(const LEX_STRING *instance_name_arg);
public:
bool init(const char **text);
protected:
virtual int execute(st_net *net, ulong connection_id);
private:
bool parse_args(const char **text);
private:
Named_value_arr options;
};
/**
Drop an instance.
Grammar: DROP INSTANCE <instance_name>
Operation is permitted only if the instance is stopped. On successful
completion the instance section is removed from config file and the instance
is removed from the instance map.
*/
class Drop_instance: public Instance_cmd
{
public:
Drop_instance(const LEX_STRING *instance_name_arg);
protected:
virtual int execute(st_net *net, ulong connection_id);
};
/**
Print requested part of the log.
Grammar:
SHOW <instance_name> LOG {ERROR | SLOW | GENERAL} size[, offset_from_end]
*/
class Show_instance_log: public Abstract_instance_cmd
{
public:
Show_instance_log(const LEX_STRING *instance_name_arg,
Log_type log_type_arg, uint size_arg, uint offset_arg);
protected:
virtual int execute_impl(st_net *net, Instance *instance);
virtual int send_ok_response(st_net *net, ulong connection_id);
private:
int check_params(Instance *instance);
int write_header(st_net *net);
int write_data(st_net *net, Instance *instance);
private:
Log_type log_type;
uint size;
uint offset;
};
/**
Shows the list of the log files, used by an instance.
Grammar: SHOW <instance_name> LOG FILES
*/
class Show_instance_log_files: public Abstract_instance_cmd
{
public:
Show_instance_log_files(const LEX_STRING *instance_name_arg);
protected:
virtual int execute_impl(st_net *net, Instance *instance);
virtual int send_ok_response(st_net *net, ulong connection_id);
private:
int write_header(st_net *net);
int write_data(st_net *net, Instance *instance);
};
/**
Abstract class for option-management commands.
*/
class Instance_options_list;
class Abstract_option_cmd: public Command
{
public:
~Abstract_option_cmd();
public:
bool add_option(const LEX_STRING *instance_name, Named_value *option);
public:
bool init(const char **text);
virtual int execute(st_net *net, ulong connection_id);
protected:
Abstract_option_cmd();
int correct_file(Instance *instance, Named_value *option, bool skip);
protected:
virtual bool parse_args(const char **text) = 0;
virtual int process_option(Instance *instance, Named_value *option) = 0;
private:
Instance_options_list *
get_instance_options_list(const LEX_STRING *instance_name);
int execute_impl(st_net *net, ulong connection_id);
private:
HASH instance_options_map;
bool initialized;
};
/**
Set an option for the instance.
Grammar: SET instance_name.option[=option_value][, ...]
*/
class Set_option: public Abstract_option_cmd
{
public:
Set_option()
{ }
protected:
virtual bool parse_args(const char **text);
virtual int process_option(Instance *instance, Named_value *option);
};
/**
Remove option of the instance.
Grammar: UNSET instance_name.option[, ...]
*/
class Unset_option: public Abstract_option_cmd
{
public:
Unset_option()
{ }
protected:
virtual bool parse_args(const char **text);
virtual int process_option(Instance *instance, Named_value *option);
};
/**
Syntax error command.
This command is issued if parser reported a syntax error. We need it to
distinguish between syntax error and internal parser error. E.g. parsing
failed because we hadn't had enought memory. In the latter case the parser
just returns NULL.
*/
class Syntax_error: public Command
{
public:
Syntax_error()
{ }
public:
int execute(st_net *net, ulong connection_id);
};
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_COMMANDS_H */
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_EXIT_CODES_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_EXIT_CODES_H
/*
Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
This file contains a list of exit codes, which are used when Instance
Manager is working in user-management mode.
*/
const int ERR_OK = 0;
const int ERR_OUT_OF_MEMORY = 1;
const int ERR_INVALID_USAGE = 2;
const int ERR_INTERNAL_ERROR = 3;
const int ERR_IO_ERROR = 4;
const int ERR_PASSWORD_FILE_CORRUPTED = 5;
const int ERR_PASSWORD_FILE_DOES_NOT_EXIST = 6;
const int ERR_CAN_NOT_READ_USER_NAME = 10;
const int ERR_CAN_NOT_READ_PASSWORD = 11;
const int ERR_USER_ALREADY_EXISTS = 12;
const int ERR_USER_NOT_FOUND = 13;
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_EXIT_CODES_H
This diff is collapsed.
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_GUARDIAN_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_GUARDIAN_H
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include <my_sys.h>
#include <my_list.h>
#include "thread_registry.h"
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
class Instance;
class Instance_map;
class Thread_registry;
/**
The guardian thread is responsible for monitoring and restarting of guarded
instances.
*/
class Guardian: public Thread
{
public:
Guardian(Thread_registry *thread_registry_arg,
Instance_map *instance_map_arg);
~Guardian();
void init();
public:
void request_shutdown();
bool is_stopped();
void lock();
void unlock();
void ping();
protected:
virtual void run();
private:
void stop_instances();
void process_instance(Instance *instance);
private:
/*
LOCK_guardian protectes the members in this section:
- shutdown_requested;
- stopped;
Also, it is used for COND_guardian.
*/
pthread_mutex_t LOCK_guardian;
/*
Guardian's main loop waits on this condition. So, it should be signalled
each time, when instance state has been changed and we want Guardian to
wake up.
TODO: Change this to having data-scoped conditions, i.e. conditions,
which indicate that some data has been changed.
*/
pthread_cond_t COND_guardian;
/*
This variable is set to TRUE, when Manager thread is shutting down.
The flag is used by Guardian thread to understand that it's time to
finish.
*/
bool shutdown_requested;
/*
This flag is set to TRUE on shutdown by Guardian thread, when all guarded
mysqlds are stopped.
The flag is used in the Manager thread to wait for Guardian to stop all
mysqlds.
*/
bool stopped;
Thread_info thread_info;
Thread_registry *thread_registry;
Instance_map *instance_map;
private:
Guardian(const Guardian &);
Guardian&operator =(const Guardian &);
};
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_GUARDIAN_H */
This diff is collapsed.
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_H
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include <m_string.h>
#include "instance_options.h"
#include "priv.h"
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
class Instance_map;
class Thread_registry;
/**
Instance_name -- the class represents instance name -- a string of length
less than MAX_INSTANCE_NAME_SIZE.
Generally, this is just a string with self-memory-management and should be
eliminated in the future.
*/
class Instance_name
{
public:
Instance_name(const LEX_STRING *name);
public:
inline const LEX_STRING *get_str() const
{
return &str;
}
inline const char *get_c_str() const
{
return str.str;
}
inline uint get_length() const
{
return str.length;
}
private:
LEX_STRING str;
char str_buffer[MAX_INSTANCE_NAME_SIZE];
};
class Instance
{
public:
/* States of an instance. */
enum enum_instance_state
{
STOPPED,
NOT_STARTED,
STARTING,
STARTED,
JUST_CRASHED,
CRASHED,
CRASHED_AND_ABANDONED,
STOPPING
};
public:
/**
The constant defines name of the default mysqld-instance ("mysqld").
*/
static const LEX_STRING DFLT_INSTANCE_NAME;
public:
static bool is_name_valid(const LEX_STRING *name);
static bool is_mysqld_compatible_name(const LEX_STRING *name);
public:
Instance();
~Instance();
bool init(const LEX_STRING *name_arg);
bool complete_initialization();
public:
bool is_active();
bool is_mysqld_running();
bool start_mysqld();
bool stop_mysqld();
bool kill_mysqld(int signo);
void lock();
void unlock();
const char *get_state_name();
void reset_stat();
public:
/**
The operation is intended to check if the instance is mysqld-compatible
or not.
*/
inline bool is_mysqld_compatible() const;
/**
The operation is intended to check if the instance is configured properly
or not. Misconfigured instances are not managed.
*/
inline bool is_configured() const;
/**
The operation returns TRUE if the instance is guarded and FALSE otherwise.
*/
inline bool is_guarded() const;
/**
The operation returns name of the instance.
*/
inline const LEX_STRING *get_name() const;
/**
The operation returns the current state of the instance.
NOTE: At the moment should be used only for guarded instances.
*/
inline enum_instance_state get_state() const;
/**
The operation changes the state of the instance.
NOTE: At the moment should be used only for guarded instances.
TODO: Make private.
*/
inline void set_state(enum_instance_state new_state);
/**
The operation returns crashed flag.
*/
inline bool is_crashed();
public:
/**
This attributes contains instance options.
TODO: Make private.
*/
Instance_options options;
private:
/**
monitoring_thread_active is TRUE if there is a thread that monitors the
corresponding mysqld-process.
*/
bool monitoring_thread_active;
/**
crashed is TRUE when corresponding mysqld-process has been died after
start.
*/
bool crashed;
/**
configured is TRUE when the instance is configured and FALSE otherwise.
Misconfigured instances are not managed.
*/
bool configured;
/*
mysqld_compatible specifies whether the instance is mysqld-compatible
or not. Mysqld-compatible instances can contain only mysqld-specific
options. At the moment an instance is mysqld-compatible if its name is
"mysqld".
The idea is that [mysqld] section should contain only mysqld-specific
options (no Instance Manager-specific options) to be readable by mysqld
program.
*/
bool mysqld_compatible;
/*
Mutex protecting the instance.
*/
pthread_mutex_t LOCK_instance;
private:
/* Guarded-instance attributes. */
/* state of an instance (i.e. STARTED, CRASHED, etc.) */
enum_instance_state state;
public:
/* the amount of attemts to restart instance (cleaned up at success) */
int restart_counter;
/* triggered at a crash */
time_t crash_moment;
/* General time field. Used to provide timeouts (at shutdown and restart) */
time_t last_checked;
private:
static const char *get_instance_state_name(enum_instance_state state);
private:
void remove_pid();
bool wait_for_stop();
private:
friend class Instance_monitor;
};
inline bool Instance::is_mysqld_compatible() const
{
return mysqld_compatible;
}
inline bool Instance::is_configured() const
{
return configured;
}
inline bool Instance::is_guarded() const
{
return !options.nonguarded;
}
inline const LEX_STRING *Instance::get_name() const
{
return &options.instance_name;
}
inline Instance::enum_instance_state Instance::get_state() const
{
return state;
}
inline void Instance::set_state(enum_instance_state new_state)
{
state= new_state;
}
inline bool Instance::is_crashed()
{
return crashed;
}
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_H */
This diff is collapsed.
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_MAP_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_MAP_H
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <hash.h>
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
class Guardian;
class Instance;
class Named_value_arr;
class Thread_registry;
extern int load_all_groups(char ***groups, const char *filename);
extern void free_groups(char **groups);
extern int create_instance_in_file(const LEX_STRING *instance_name,
const Named_value_arr *options);
/**
Instance_map - stores all existing instances
*/
class Instance_map
{
public:
/**
Instance_map iterator
*/
class Iterator
{
private:
uint current_instance;
Instance_map *instance_map;
public:
Iterator(Instance_map *instance_map_arg) :
current_instance(0), instance_map(instance_map_arg)
{}
void go_to_first();
Instance *next();
};
public:
Instance *find(const LEX_STRING *name);
bool is_there_active_instance();
void lock();
void unlock();
bool init();
bool reset();
int load();
int process_one_option(const LEX_STRING *group, const char *option);
int add_instance(Instance *instance);
int remove_instance(Instance *instance);
int create_instance(const LEX_STRING *instance_name,
const Named_value_arr *options);
public:
Instance_map();
~Instance_map();
private:
bool complete_initialization();
private:
enum { START_HASH_SIZE = 16 };
pthread_mutex_t LOCK_instance_map;
HASH hash;
private:
friend class Iterator;
};
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_MAP_H */
This diff is collapsed.
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_OPTIONS_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_OPTIONS_H
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include <my_sys.h>
#include "parse.h"
#include "portability.h" /* for pid_t on Win32 */
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
/*
This class contains options of an instance and methods to operate them.
We do not provide this class with the means of synchronization as it is
supposed that options for instances are all loaded at once during the
instance_map initilization and we do not change them later. This way we
don't have to synchronize between threads.
*/
class Instance_options
{
public:
/* The operation is used to check if the option is IM-specific or not. */
static bool is_option_im_specific(const char *option_name);
public:
Instance_options();
~Instance_options();
bool complete_initialization();
bool set_option(Named_value *option);
void unset_option(const char *option_name);
inline int get_num_options() const;
inline Named_value get_option(int idx) const;
public:
bool init(const LEX_STRING *instance_name_arg);
pid_t load_pid();
int get_pid_filename(char *result);
int unlink_pidfile();
void print_argv();
uint get_shutdown_delay() const;
int get_mysqld_port() const;
public:
/*
We need this value to be greater or equal then FN_REFLEN found in
my_global.h to use my_load_path()
*/
enum { MAX_PATH_LEN= 512 };
enum { MAX_NUMBER_OF_DEFAULT_OPTIONS= 2 };
char pid_file_with_path[MAX_PATH_LEN];
char **argv;
/*
Here we cache the version string, obtained from mysqld --version.
In the case when mysqld binary is not found we get NULL here.
*/
const char *mysqld_version;
/* We need the some options, so we store them as a separate pointers */
const char *mysqld_socket;
const char *mysqld_datadir;
const char *mysqld_pid_file;
LEX_STRING instance_name;
LEX_STRING mysqld_path;
LEX_STRING mysqld_real_path;
const char *nonguarded;
/* log enums are defined in parse.h */
char *logs[3];
private:
bool fill_log_options();
bool fill_instance_version();
bool fill_mysqld_real_path();
int add_to_argv(const char *option);
int get_default_option(char *result, size_t result_len,
const char *option_name);
void update_var(const char *option_name, const char *option_value);
int find_option(const char *option_name);
private:
const char *mysqld_port;
uint mysqld_port_val;
const char *shutdown_delay;
uint shutdown_delay_val;
uint filled_default_options;
MEM_ROOT alloc;
Named_value_arr options;
};
inline int Instance_options::get_num_options() const
{
return options.get_size();
}
inline Named_value Instance_options::get_option(int idx) const
{
return options.get_element(idx);
}
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_OPTIONS_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -7499,10 +7499,7 @@ SHOW_VAR status_vars[]= {
static void print_version(void)
{
set_server_version();
/*
Note: the instance manager keys off the string 'Ver' so it can find the
version from the output of 'mysqld --version', so don't change it!
*/
printf("%s Ver %s for %s on %s (%s)\n",my_progname,
server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
}
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment