[我会陆续推出有关mysql架构的文章,希望能给大家带来帮助!]
先贴张图,大家常见的。
环境:
Centos5.2
Mysql 5.1.44
Master:192.168.x.166
Slaver:192.168.x.172
Master数据库安装操作
下载mysql
http://dev.mysql.com/downloads/
安装源码
参考INSTALL-SOURCE
shell> groupadd mysql
shell> useradd -g mysql mysql
shell> gunzip < mysql-VERSION.tar.gz | tar -xvf -
shell> cd mysql-VERSION
shell> ./configure --prefix=/usr/local/mysql
shell> make
shell> make install
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> cd /usr/local/mysql
shell> chown -R mysql .
shell> chgrp -R mysql .
shell> bin/mysql_install_db --user=mysql
shell> chown -R root .
shell> chown -R mysql var
shell> bin/mysqld_safe --user=mysql &
不同之处在与编译,我采取的是优化方面的编译参数
CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors \
-fno-exceptions -fno-rtti -fomit-frame-pointer -ffixed-ebp"
./configure \
--prefix=/usr/local/mysql --enable-assembler \
--with-mysqld-ldflags=-all-static \
--with-client-ldflags=-all-static \
--with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock \
--with-charset=utf8 \
--with-collation=utf8_general_ci \
--with-extra-charsets=all
并且设置自动启动
(1)Chmod +x support-files/mysql.server
(2)cp support-files/mysql.server /etc/init.d/mysqld
(3)chkconfig �Cadd mysqld
(4)chkconfig �Clevel 345 mysqld on
(5)service mysqld start/stop测试
Slave数据库安装操作如上。
主从设置
需要复制的数据库为:shops
mysql> desc user;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name | char(30) | NO | | NULL | |
+-------+----------+------+-----+---------+-------+
1 row in set (0.00 sec)
Master端配置
(1)修改my.cnf配置文件
[mysqld]
port = 3306
socket = /usr/local/mysql/tmp/mysql.sock
skip-external-locking
key_buffer_size = 16M
max_allowed_packet = 1M
table_open_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
log-bin=mysql-bin
binlog_format=mixed
server-id = 1
binlog-do-db=shops
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
(2)给予用户复制权限
grant replication slave on *.* to 'repbadboy'@'192.168.x.172' identified by '111111';
flush privileges;
在借用mysqldump的―master-data备份数据的前提下,就需要二进制日志功能开启,所以在这前,没有开启的朋友,需要(配置my.cnf开启log-bin见上面)重启下mysql服务喽。在此申明,这些所有的操作,都应该在用户量非常少得情况下使用。
注:--master-data,这个参数作用:mysqldump会在dump文件中产生一条change master to命令,命令中记录了dump时刻所对应的详细的Log Position信息。如下:
[root@centos01 mysql]# more /tmp/shops.sql|grep "CHANGE MASTER"
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=199;
(3)备份shops数据(Mysqldump)
[a.] flush tables with read lock;( 全局读锁定)
[b.]show master status\G(这个要记住,或者到mysqldump后的dump文件中找有关log与log_pos有关的数据)
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 199
Binlog_Do_DB: shops
Binlog_Ignore_DB:
1 row in set (0.00 sec)
这个数据应该与mysqldump中的dump文件的信息是一样的。
[c.] bin/mysqldump --master-data shops >/tmp/shops.sql
[e.]unlock tables;
从服务器配置
(1)恢复shops数据(创建shops库)
Mysql shops< /tmp/shops.sql
(2)从数据库的my.cnf配置
[client]
port = 3306
socket = /usr/local/mysql/tmp/mysql.sock
[mysqld]
port = 3306
socket = /usr/local/mysql/tmp/mysql.sock
skip-external-locking
key_buffer_size = 16M
max_allowed_packet = 1M
table_open_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
#log-bin=mysql-bin
#binlog_format=mixed
server-id = 2
replicate-do-db=shops
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
(3) change master to master_host='192.168.x.166' ,master_user='repbadboy', master_password='111111' ,master_log_file='mysql-bin.00001',master_log_pos=199;
(4)Start slave
a. (如果重启了master服务器,那么Slave服务器只需等待默认的60秒(Connect_Retry)就会重新连接来完成复制工作)
测试流程,如下:
[测试模拟背景:起初,网站比较小,数据提供仅一台mysql。后期发现,一台mysql无法为客户提供优质的访问了,为此需要采用mysql复制技术,一方面做到读写分离,提高性能,另一方面保障了数据的安全。]
假设数据需要复制的数据库为shops,表为user,
mysql> desc user;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name | char(30) | NO | | NULL | |
+-------+----------+------+-----+---------+-------+
1 row in set (0.00 sec)
因运行了一段时间,肯定有数据的,如下:
mysql> select * from user;
+----------+
| name |
+----------+
| badboy01 |
| badboy02 |
| badboy03 |
| badboy04 |
| badboy05 |
+----------+
5 rows in set (0.00 sec)
记住,这是我们在没有决定使用复制功能时的数据,现在。我们要使用复制这个功能了,所以,为了要让从服务器与主服务器数据一致,需要如下操作:
(1) 修改其my.cnf(开启日志功能)
log-bin=mysql-bin
binlog_format=mixed
server-id = 1
binlog-do-db=shops
具体其他的参数见我上面贴的。
(2) 添加复制帐号
grant replication slave on *.* to 'repbadboy'@'192.168.x.172' identified by '111111';
(3) 重启service mysqld restart
再次假设,重启后就有部分数据更新。如:
mysql> select * from user;
+----------+
| name |
+----------+
| badboy01 |
| badboy02 |
| badboy03 |
| badboy04 |
| badboy05 |
| badboy06 |?
| badboy07 |?注意这两个数据是重启数据库后更新的数据,但然如果访问量真的很大的话,会出现这种情况的,不过,它已经被记录到二进制日志中了。不用担心。。。
+----------+
7 rows in set (0.00 sec)
(4)
mysql> flush tables with read lock;(锁表)
Query OK, 0 rows affected (0.00 sec)
mysql> show master status\G(查看master状态)
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 304
Binlog_Do_DB: shops
Binlog_Ignore_DB:
1 row in set (0.00 sec)
mysql>
(4) bin/mysqldump --master-data shops >/tmp/shops.sql (mysqldump备份数据)
查看:
[root@centos01 mysql]# more /tmp/shops.sql |grep "CHANGE MASTER"
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=304; (5)unlock tables;
再再次假设,但解锁后,又有部分数据插入。如下:
mysql> select * from user;
+----------+
| name |
+----------+
| badboy01 |
| badboy02 |
| badboy03 |
| badboy04 |
| badboy05 |
| badboy06 |
| badboy07 |
| badboy08 |?
| badboy09 |?
| badboy10 |?这3条数据是在解锁后插入的。
+----------+
10 rows in set (0.00 sec)
现在Master端的工作已经做完,现在准备做slave端。
(1) 配置my.cnf
#log-bin=mysql-bin
#binlog_format=mixed
server-id = 2
replicate-do-db=shops、
具体配置见上面.
重启service mysqld restart
(2) 恢复shops
恢复之前看下mysql数据存放位置的文件
[root@centos01 mysql]# ls var/
centos01.tianciyt.com.cn.err centos01.tianciyt.com.cn.pid mysql shops test
bin/mysql shops< /tmp/shops.sql
恢复后看下mysql数据存放位置的文件
[root@centos01 mysql]# ls var/
centos01-relay-bin.000001 centos01.tianciyt.com.cn.err master.info relay-log.info test
centos01-relay-bin.index centos01.tianciyt.com.cn.pid mysql shops
[点评]这就是―master-data的作用所在。
(3) 查看下当前的数据情况
mysql> select * from user;
+----------+
| name |
+----------+
| badboy01 |
| badboy02 |
| badboy03 |
| badboy04 |
| badboy05 |?这是在没有开启二进制日志时的数据
| badboy06 |
| badboy07 |?这是在开启二进制日志时并且在全局读锁定之前的数据,(此时预言)还有badboy08, badboy09, badboy10……应该在我们配置好slave后,可以复制过来的。
+----------+
7 rows in set (0.00 sec)
(4)查看slave状态
mysql> show slave status\G
Empty set (0.00 sec)
(5) 启动slave准备
change master to master_host='192.168.x.166' ,master_user='repbadboy', master_password='111111',MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=304;
这两个标红色的,应该注意到与上面的shops.sql和show master status\G是一样的。
[再看下shops.sql
[root@centos01 mysql]# more /tmp/shops.sql|grep "CHANGE MASTER"
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=304;
]
最后,
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
(6) 查看到slave状态
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.x.166
Master_User: repbadboy
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 601
Relay_Log_File: centos01-relay-bin.000002
Relay_Log_Pos: 548
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: shops
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 601
Relay_Log_Space: 706
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
1 row in set (0.00 sec)
(7)检查数据
mysql> select * from user; +----------+
| name |
+----------+
| badboy01 |
| badboy02 |
| badboy03 |
| badboy04 |
| badboy05 |
| badboy06 |
| badboy07 |
| badboy08 |?
| badboy09 |?
| badboy10 |?这三条数据就是我预言的证明,哈哈。我们再来试试。。
+----------+
10 rows in set (0.00 sec)
(7) 再测试下,在master插入badboy11,badboy12。。。
mysql> insert into user values('badboy11');
Query OK, 1 row affected (0.00 sec)
mysql> insert into user values('badboy12');
Query OK, 1 row affected (0.00 sec)
查看master数据
mysql> select * from user;
+----------+
| name |
+----------+
| badboy01 |
| badboy02 |
| badboy03 |
| badboy04 |
| badboy05 |
| badboy06 |
| badboy07 |
| badboy08 |
| badboy09 |
| badboy10 |
| badboy11 |
| badboy12 |
+----------+
12 rows in set (0.01 sec)
再查看slave端如何,
mysql> select * from user;
+----------+
| name |
+----------+
| badboy01 |
| badboy02 |
| badboy03 |
| badboy04 |
| badboy05 |
| badboy06 |
| badboy07 |
| badboy08 |
| badboy09 |
| badboy10 |
| badboy11 |
| badboy12 |
+----------+
12 rows in set (0.01 sec)
好了,所有测试都完整了。我想这也算一篇详尽的文章了吧。供大家参考。