博客是我工作的好帮手,遇到困难就来博客找资料
分类: 系统运维
2015-04-28 11:12:57
1复制准备主库(mysql master): ip为192.168.1.5 port为3306从库(mysql slave): ip为192.168.1.4 port为3306数据库环境准备,具备两台服务器每个机器一个数据库的环境.2.主库上执行操作2.1设置server-id值并开启binlog参数根据mysql的同步原理,我们知道复制的关键因素就是binlog日志.执行vi /etc/my.cnf编辑my.cnf配置文件,按如下两个参数内容修改:[mysqld]server-id = 1log-bin = mysql-bi提示:1.上面两参数放在my.cnf中的[mysqld]模块下,否则会出错;2.要先在my.cnf文件中查找相关参数,并按要求修改,不存在时在添加参数,切记,参数不能重复;3.修改my.cnf配置后需要重启数据库命令为:/etc/init.d/mysql restart,注意确认真正重启了(此处数据库为源码包安装,在后面我将贴出mysql的启动脚本)。检查配置后的结果(这是一个好的习惯):grep -E "server-id|log-bin" /etc/my.cnf 和egrep一样的作用 /etc/init.d/mysql restart2.2建立用于同步的账号rep登陆mysql 3306实例主数据库mysql -uroot -p'123123' -S /tmp/mysql.sockmysql>select user(); 查看用户mysql>grant replication slave on *.* to 'rep'@'192.168.1.%' identified by "123456"; 建立用于库复制的账号rep#replication slave为mysql同步的必须权限,此处不要授权all#*.*表示所有库所有表,库也是可以指定具体的库和表进行复制,如test.test1(test库的test1表);#'rep'@'192.168.1.%' rep为同步账号,192.168.1.%为授权主机,使用了%表示允许整个192.168.1.0网段以rep用户访问;#identified by "123456" , 123456为密码,实际环境时复杂一点为好。再次检查创建的rep账号select user.host from mysql.user;也可以查看用户权限 mysql>show grants for rep@'192.168.1.%';2.3对数据库锁表只读(当前窗口不要关闭)生产环境时,操作主从复制,需要申请停机时间,锁表会影响业务。mysql>flush tables with read lock;提示,这个锁表命令的时间,在不同引擎的情况,会受下面参数的控制,锁表时,如果超过设置时间不操作会自动解锁;interactive_timeout = 60wait_timeout = 60默认情况下的时长为:mysql>show variables like "%timeout%"; 可以查看到默认值很大完成后测试下是否锁表,打开另一窗口创建一test1表,是不会执行的,证明锁表不能更新,但可读,不可写,因为是read读锁,锁表主要是为了导出数据库文件,从而取得正确的偏移量的值,保证导入从数据库,数据一致。2.4查看主库状态查看主库状态,即当前日志文件名和二进制日志偏移量show master status;命令显示的信息要记录在案,后面的从库复制时是从这个位置开始的。2.5导出数据库数据单开新窗口,导出数据库数据,如果数据库量很大(100G+),并且允许停机可以,可以直接停库打包数据文件迁移。mkdir /server/backup/ -pmysqldump -uroot -p"123123" -S /tmp/mysql.sock -A -B | gzip > /server/backup/mysql_bak.$(date +%F).sql.gz#注意,-A表示备份所有库, -B表示增加user DB和drop等参数(导库时会直接覆盖所有的)。ls -l /server/backup/mysql_bak.$(date +%F).sql.gz为了确保导库期间,数据库没有数据插入,可以再检查下主库状态信息mysql -uroot -p"123123" -S /tmp/mysql.sock -e "show master status"提示,无特殊情况,binlog文件及位置点是保持不变的。导库后,解锁主库,恢复可写;mysql>unlock tables;特别提示,有读者这里犯迷糊,实际上做从库的,无论主库更新多少数据了,最后从库都会从上面show master status 的位置很快赶上主库的位置进度的。2.6把主库备份的mysql数据迁移到从库这步常用命令有scp,rsync等。ls -l /server/backup/mysql_bak.$(date +%F).sql.gz
在此说明下:在最后试验过程中,当查看从库状态的时候,IO_Running显示为no,从error_log中看到如下报错提示:120523 0:55:31 [Note] Slave I/O thread: connected to master 'rep@192.168.1.5:3306', replication started in log ' mysql-bin.000004' at position 1273120523 0:55:31 [ERROR] Error reading packet from server: Could not find first log file name in binary log index file ( server_errno=1236)120523 0:55:31 [ERROR] Got fatal error 1236: 'Could not find first log file name in binary log index file' from master when reading data from binary log错误代码为1236我的解决方法为:重新检查授权,确认无误,重新按前面步骤记录偏移量,二进制文件,停止从数据库,然后重新在从数据库中CHANGE MASTER TO 开始,指向正确的二进制文件及偏移量.如下图:下面我将贴出mysql的启动脚本(仅作参考)
#!/bin/bash
mysql_user="root"
mysql_pwd="123123"
CmdPath="/usr/local/mysql/bin"
function_start()
{
printf "Starting MySQL...\n"
/bin/sh ${CmdPath}/mysqld_safe --defaults-file=/etc/my.cnf >/dev/null 2>&1 &
}
function_stop()
{
printf "Stoping MySQL...\n"
${CmdPath}/mysqladmin -u${mysql_user} -p${mysql_pwd} -S /tmp/mysql.sock shutdown >/dev/null
}
function_restart()
{
printf "Restarting MySQL...\n"
function_stop
sleep 2
function_start
}
case $1 in
start)
function_start
;;
stop)
function_stop
;;
restart)
function_restart
;;
*)
printf "Usage: $0 {start|stop|restart}\n"
esac
生产环境在工作时间轻松配置从库在定时任务备份时,每天的夜里服务里压力小时侯的定时备份时做一些措施即可,如1.锁表备份全备一份;2.锁表前后取得show master status值记录日志里.这样可以在白天从容的实现主从同步了,如下面脚本:#!/bin/bashMYUSER=rootMYPASS="123123"MYSOCK=/tmp/mysql.sock MAIN_PATH=/server/backupDATA_PATH=/server/backupLOG_FILE=${DATA_PATH}/mysqllogs_`date +%F`.logDATA_FILE=${DATA_PATH}/mysql_backup_`date +%F`.sql.gz MYSQL_PATH=/usr/local/mysql/binMYSQL_CMD="$MYSQL_PATH/mysql -u$MYUSER -p$MYPASS -S $MYSOCK"MYSQL_DUMP="$MYSQL_PATH/mysqldump -u$MYUSER -p$MYPASS -S $MYSOCK -A -B --flush-logs --single-transaction -e" $MYSQL_CMD -e "flush tables with read lock;"echo "---------show master status result---------" >> $LOG_FILE$MYSQL_CMD -e "show master status;" >> $LOG_FILE${MYSQL_DUMP} | gzip > $DATA_FILE$MYSQL_CMD -e "unlock tables;"mail -s "mysql slave log" 123456@163.com < $LOG_FILE5.相关mysql技术技巧概览5.1配置忽略权限库同步参数binlog-ignore"db"information_schemabinlog_ignore"db"mysql5.2主从复制故障解决show slave status报错:Error xxx don't exist且show slave status\G;Slave_IO_Running: YesSlave_SQL_Running : NoSeconds_Behind_Master: NULL解决方法:stop slave;set global sql_slave_skip_counter=1;start slave;这样slave就会和master去同步,主要看点:secon是否为0 # 0表示已经同步状态提示: set global sql_slave_skip_counter=n; # n取值 >0忽略执行N个更新5.3让mysql slave记录binlog方法在从库的my.cnf中加入如下参数log-slave=updateslog-bin=mysql3306-binexpize_logs_days = 7应用场景:级联复制或从库做数据备份5.4严格设置从库只读read-only的妙用5.5生产环境如何确保从库只读?1)mysql从服务器中加入read-only参数或者在从服务器启动时加该参数;2)忽略mysql库及information_schema库同步;3)授权从库用户时仅授权select权限.
1
2
3
4
5
6
7
8
|
# yum -y install perl-Time-HiRes
# wget
# tar -zxvpf percona-toolkit-2.2.13.tar.gz
# cd percona-toolkit-2.2.13
# perl Makefile.PL
# make
# make install
|
1
|
binlog_format=ROW
|
1
2
3
4
5
|
# pt-table-checksum --user=root --password=123456 \
--host=192.168.1.205 --port=3306 \
--databases=test --tables=t2 --recursion-method=processlist \
--no-check-binlog-format --nocheck-replication-filters \
--replicate=test.checksums
|
1
2
|
# pt-table-sync --execute --replicate \
test.checksums --sync-to-master h=192.168.1.207,P=3306,u=root,p=123456
|
1
2
3
4
5
6
7
8
|
SELECT
*
FROM
test.checksums
WHERE
master_cnt <> this_cnt
OR master_crc <> this_crc
OR ISNULL(master_crc) <> ISNULL(this_crc)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
mysql> create table t2 (id int primary key,name varchar(100) not null,salary int);
mysql> CREATE PROCEDURE test_insert ()
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i<10000
DO
INSERT INTO t2
VALUES
(i,CONCAT('员工',i), i);
SET i=i+1;
END WHILE ;
END;;
mysql> CALL test_insert();
|
1
2
3
4
5
6
7
8
9
10
|
mysql> delete from t2 where id > 5000;
Query OK, 4999 rows affected (0.14 sec)
mysql> select count(*) from t2;
+----------+
| count(*) |
+----------+
| 5001 |
+----------+
1 row in set (0.01 sec)
|
1
2
3
4
5
|
# pt-table-checksum --user=root --password=123456 \
--host=192.168.1.205 --port=3306 \
--databases=test --tables=t2 --recursion-method=processlist \
--no-check-binlog-format --nocheck-replication-filters \
--replicate=test.checksums
|
1
2
3
4
5
6
7
8
|
mysql> SELECT
*
FROM
test.checksums
WHERE
master_cnt <> this_cnt
OR master_crc <> this_crc
OR ISNULL(master_crc) <> ISNULL(this_crc)
|
1
2
|
# pt-table-sync --execute --replicate \
test.checksums --sync-to-master h=192.168.1.207,P=3306,u=root,p=123456
|
1
2
|
character_set_client=utf8
character_set_server=utf8
|
1
2
3
|
# pt-table-sync --execute --replicate \
test.checksums --charset=utf8 \
--sync-to-master h=192.168.1.207,P=3306,u=root,p=123456
|