mysql多实例双主部署
有的时候需要进行数据库环境的隔离,以及节省服务器资源
一台mysql安装多个数据库实例,一个实例下构建多个数据库
安装mysql
yum -y install ncurses-devel cmake wget gcc gcc-c++ &&
cd /usr/local/src &&
wget http://192.168.1.173:8000/mysql-5.6.23.tar.gz &&
groupadd mysql && useradd mysql -g mysql
在mysql解压包目录下,执行如下编译安装脚本:
cd /usr/local/src &&
rm -rf mysql-5.6.23 &&
tar -zxvf mysql-5.6.23.tar.gz && cd mysql-5.6.23 &&
rm -rf /etc/my.cnf /usr/local/mysql &&
mkdir -p /usr/local/mysql /usr/local/mysql/mysql_data &&
rm -rf CMakeCache.txt &&
cmake . \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/usr/local/mysql/mysql_data \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_DEBUG=1 &&
make -j `cat /proc/cpuinfo |grep processor|wc -l` && make install &&
cp /usr/local/mysql/support-files/mysql.server \
/etc/init.d/mysqld &&
chkconfig mysqld --level 35 on
ln -s /usr/local/mysql/bin/mysql /usr/local/bin/mysql
ln -s /usr/local/mysql/bin/mysqladmin /usr/local/bin/mysqladmin
ln -s /usr/local/mysql/bin/mysqld_multi /usr/local/bin/mysqld_multi
ln -s /usr/local/mysql/bin/my_print_defaults /usr/local/bin/my_print_defaults
wget http://192.168.1.173:8000/my.cnf -O /usr/local/mysql/my.cnf
ln -s /usr/local/mysql/my.cnf /etc/my.cnf
mkdir -p /data0/mysql /data1/mysql /data2/mysql
chown mysql.mysql /etc/init.d/mysqld /data0/mysql /data1/mysql /data1/mysql &&
chmod u+x /etc/init.d/mysqld &&
chown -R mysql.mysql /usr/local/mysql/
初始化实例
rm -rf /data1/mysql/data3306/*
/usr/local/mysql/scripts/mysql_install_db \
--basedir=/usr/local/mysql \
--datadir=/data1/mysql/data3306
rm -rf /data1/mysql/data3307/*
/usr/local/mysql/scripts/mysql_install_db \
--basedir=/usr/local/mysql \
--datadir=/data1/mysql/data3307
rm -rf /data1/mysql/data3308/*
/usr/local/mysql/scripts/mysql_install_db \
--basedir=/usr/local/mysql \
--datadir=/data1/mysql/data3308
mkdir -p /data1/mysql/{log3308,log3308,log3308}
mkdir -p /data0/log-bin/{log3308,log3308,log3308}
mkdir -p /usr/local/mysql/tmp
chown -R mysql.mysql \
/data0/mysql \
/data1/mysql \
/data0/log-bin \
/usr/local/mysql/
修改配置文件
多实例的主配置文件也只有一个:
vim /usr/local/mysql/my.cnf
确认如下内容:
# para for mysql
# author : thy
[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
user = mysql
[mysqld3306]
[mysqld3307]
[mysqld3308]
basedir = /usr/local/mysql/
datadir = /data1/mysql/data3308
socket = /data1/mysql/data3308/mysql.sock
pid-file = /data1/mysql/data3308/mysqld.pid
tmpdir=/tmp
lc_messages_dir=/usr/local/mysql/share
log-error = /data1/mysql/log3308/error.log
general_log_file=/data1/mysql/log3308/general.log
slow_query_log = 2
slow_query_log_file = /data1/mysql/log3308/slow.log
log_bin_trust_function_creators=1
user = mysql
port = 3308
#binlog path
log-bin=/data0/log-bin/log3308/mysql-bin
server_id=2083308
binlog_cache_size=32K
max_binlog_cache_size=2G
max_binlog_size=500M
binlog-format=ROW
sync_binlog=1000
log-slave-updates=1
expire_logs_days=0
master-info-file=/data1/mysql/log3308/master.info
relay-log=/data1/mysql/log3308/relaylog
relay_log_info_file=/data1/mysql/log3308/relay-log.info
relay-log-index=/data1/mysql/log3308/mysqld-relay-bin.index
slave_load_tmpdir=/usr/local/mysql/tmp
slave_type_conversions="ALL_NON_LOSSY"
slave_net_timeout=4
skip-slave-start
sync_master_info=1000
sync_relay_log_info=1000
skip_external_locking
key_buffer_size = 256M
max_allowed_packet = 128M
thread_stack = 512K
table_open_cache = 5120
sort_buffer_size = 6M
read_buffer_size = 4M
join_buffer_size = 8M
myisam_sort_buffer_size = 128M
thread_cache_size = 64
query_cache_size = 128M
tmp_table_size = 256M
back_log = 500
max_connections = 1000
max_connect_errors = 10000000
thread_concurrency = 8
explicit_defaults_for_timestamp = TRUE
event_scheduler=on
interactive_timeout=288000
wait_timeout=288000
lock_wait_timeout=30
concurrent_insert=2
#server
default-storage-engine=MyIsam
default-tmp-storage-engine=MyIsam
character-set-server=utf8
lower_case_table_names=1
skip-external-locking
open_files_limit=655360
safe-user-create
local-infile=1
#sqlmod="STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE"
performance_schema=0
skip-name-resolve
skip-ssl
connect_timeout=8
net_read_timeout=30
net_write_timeout=60
启动多实例
mysqld_multi --defaults-extra-file=/usr/local/mysql/my.cnf report
mysqld_multi \
--defaults-extra-file=/usr/local/mysql/my.cnf \
--log=/usr/local/mysql/mysqld3306.log \
start 3306
mysqld_multi \
--defaults-extra-file=/usr/local/mysql/my.cnf \
--log=/usr/local/mysql/mysqld3307.log \
start 3307
mysqld_multi \
--defaults-extra-file=/usr/local/mysql/my.cnf \
--log=/usr/local/mysql/mysqld3308.log \
start 3308
查看是否启动成功:
ps -ef |grep mysql
netstat -antp |grep LIST|grep mysql
关闭多实例
强行关闭全部mysql实例:
pkill mysql
mysqladmin -uroot -S /data1/mysql/data3306/mysql.sock shutdown
mysqladmin -uroot -S /data1/mysql/data3307/mysql.sock shutdown
mysqladmin -uroot -S /data1/mysql/data3308/mysql.sock shutdown
强行关闭多实例
netstat -antp |grep LIST|grep 3306 |awk '{printf $NF}'|awk -F / '{print $1}'|xargs -t -i kill -9 {}
netstat -antp |grep LIST|grep 3307 |awk '{printf $NF}'|awk -F / '{print $1}'|xargs -t -i kill -9 {}
netstat -antp |grep LIST|grep 3308 |awk '{printf $NF}'|awk -F / '{print $1}'|xargs -t -i kill -9 {}
netstat -antp |grep LIST|grep mysql
cat /data0/mysql/data3306/error.log
cat /data0/mysql/data3307/error.log
cat /data0/mysql/data3308/error.log
登录多实例
mysql -uroot -S /data1/mysql/data3306/mysql.sock
mysql -uroot -S /data1/mysql/data3307/mysql.sock
mysql -uroot -S /data1/mysql/data3308/mysql.sock
初始化账号
select * from mysql.user;
delete from mysql.user where user='';
update mysql.user set host='%' where host='dcmysql1' and user='root';
update mysql.user set host='%' where host='dcserver2' and user='root';
update mysql.user set host='%' where host='mysql9' and user='root';
update mysql.user set host='%' where host='mysql10' and user='root';
update mysql.user set password=Password('password') where user='root' and host='%';
flush privileges;
配置双主环境
1、先分别情况两个实例的主从同步配置
reset master;
stop slave;
reset slave;
show master status \G
执行后,binlog目录会清空,只剩下两个文件:mysql-bin.000001和mysql-bin.index
并且两个实例的master状态都是:
show master status \G
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 120
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
2、配置my.cnf
分别在两个实例上添加如下配置,注意server-id必须不同,其他参数相同:
在实例1上配置:
vim /usr/local/mysql/my.cnf
添加如下内容:
server-id=10001
log-bin=mysql-bin
innodb_flush_log_at_trx_commit=1
sync_binlog=1
log-slave-updates
binlog-ignore-db=mysql,test
replicate-ignore-db=test,mysql,information_schema
#replicate-do-db = dataeye1
#replicate-do-db = dataeye2
#replicate-do-table = table1
#replicate-do-table = table2
在实例2上配置:
vim /usr/local/mysql/my.cnf
添加如下内容:
server-id=10002
log-bin=mysql-bin
innodb_flush_log_at_trx_commit=1
sync_binlog=1
log-slave-updates
binlog-ignore-db=mysql,test
replicate-ignore-db=test,mysql,information_schema
#replicate-do-db = dataeye1
#replicate-do-db = dataeye2
#replicate-do-table = table1
#replicate-do-table = table2
3、创建同步账号并重置master
分别在两个实例上创建同步账号并重置master信息:
GRANT REPLICATION SLAVE ON *.* TO 'master'@'%' IDENTIFIED BY 'master';
flush privileges;
stop slave;
reset master;
flush tables with read lock;
注意:
必须先在两个实例都创建了同步账号,停用了slave,重置master信息以后,
才执行CHANGE MASTER操作。
如果连着操作就会出现一个问题:
节点1作为从节点,能正常同步节点2的数据,
但是节点2做为从节点不能同步节点1的数据。
### 4、配置节点1
登录实例1,执行如下sql(注意节点2的配置跟1有关):
CHANGE MASTER TO MASTER_HOST='192.168.1.141',\
MASTER_PORT=3306,\
MASTER_USER='master', \
MASTER_PASSWORD='master', \
MASTER_LOG_FILE='mysql-bin.000001', \
MASTER_LOG_POS=120;
unlock tables;
flush privileges;
start slave;
show slave status \G
show master status \G
结果如下:
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 199
注意:
执行如上sql后,节点1的Position会从120变为其他值,如199
5、配置节点2
根据1的master信息的Position,执行如下sql:
CHANGE MASTER TO MASTER_HOST='192.168.1.141',\
MASTER_PORT=3306,\
MASTER_USER='master', \
MASTER_PASSWORD='master', \
MASTER_LOG_FILE='mysql-bin.000001', \
MASTER_LOG_POS=199;
unlock tables;
flush privileges;
start slave;
show slave status \G
show master status \G
注意:
这里的MASTER_LOG_POS不是120了,必须是当前节点1的Position。
否则也会出现其中一个节点的同步问题:
节点1作为从节点,能正常同步节点2的数据,
但是节点2做为从节点不能同步节点1的数据。
常用命令
清空节点主从配置
reset master;
stop slave;
reset slave;
show master status \G
查看从节点状态:
show slave status \G
查看从节点IP:
show slave hosts \G
查看主节点状态:
show master status \G (更详细)
show master logs \G
查看节点server id
show variables like 'server_id' \G
show variables like 'server_uuid' \G
查看binlog变更日志
show binlog events;
查看同步进度和连接情况
show processlist;
查看其它全局参数
show variables like 'innodb_data_file_path' \G
show variables like 'innodb_force_recovery' \G
锁定所有表
flush tables with read lock;
锁定单个表
例如锁定表tables1不能读,只能写,
锁定表tables2可以读,不能写。
LOCK TABLES tables1 WRITE, table2 WRITE;
解锁所有表
unlock tables;
查看表状态:
use database1;
show table status;
常见问题
报错1
双主环境中,在主节点插入数据后,在从节点发现报错:
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'could not find next log; the first event 'mysql-bin.000001' at 4, the last event read from
'./mysql-bin.000002' at 399, the last byte read from './mysql-bin.000002' at 399.'
这是因为主主同步默认配置中的MASTER_LOG_FILE和MASTER_LOG_POS 指定了同步其实位置,但这个位置上不连续的,中间可能被清理过一次。
解决方法:
1、登录slave节点:
stop slave;
2、登录master节点:
flush logs;
show master status;
3、回到slave节点,根据master的节点位置重新指定同步位置并启动slave:
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002',MASTER_LOG_POS=120;
start slave;
报错2
./error.log:101:2016-02-18 17:27:23 15334 [ERROR] Slave SQL:
Error 'Can't create database 'data22222222222222'; database exists' on query. Default database:
'data22222222222222'. Query: 'CREATE DATABASE `data22222222222222`', Error_code: 1007
解决:
vim /usr/local/mysql/my.cnf
添加如下一行:
slave-skip-errors=all
报错3
修复表报错:
Error: /usr/local/mysql/bin/mysqlcheck doesn't support
multiple contradicting commands.
表结构修复:
/usr/local/mysql/bin/mysqlcheck \
--defaults-extra-file=/usr/local/mysql/my.cnf \
-S /data0/mysql/data3308/mysql.sock \
-r --databases mysql
多实例修复数据库时不支持--optimize参数:
/usr/local/mysql/bin/mysqlcheck \
--auto-repair \
--check --optimize \
--all-databases