主從的作用:
1.可以當做一種備份方式
2.用來實現讀寫分離,緩解一個數據庫的壓力
MySQL主從備份原理:
Mysql的主從復制至少是需要兩個Mysql的服務,當然Mysql的服務是可以分布在不同的服務器上,也可以在一台服務器上啟動多個服務。
如果想配置成為同一台上的話,注意安裝的時候,選擇兩個不同的prefix=路徑,同時開啟服務器的時候,端口不能相同。
(1)首先確保主從服務器上的Mysql版本相同(做主從服務器的原則是,MYSQL版本要相同,如果不能滿足,最起碼從服務器的MYSQL的版本必須高於主服務器的MYSQL版本 )
(2)在主服務器上,設置一個從數據庫的賬戶,使用REPLICATION SLAVE賦予權限,如:
復制代碼 代碼如下:
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave001'@'192.168.0.99' IDENTIFIED BY
'123456';
Query OK, 0 rows affected (0.13 sec)
[原理]master 上提供binlog ,
slave 通過 I/O線程從 master拿取 binlog,並復制到slave的中繼日志中
slave 通過 SQL線程從 slave的中繼日志中讀取binlog ,然後解析到slave中
主從復制大前提
需要master與slave同步,因為筆者的數據庫數據量不大,所以無需考慮太多,直接把
master上的data復制到了slave上,但是如果是大的數據量,比如像taobao這個的系統
實驗環境准備:
OS: CentOS5.4
Mysql:Mysql-5.0.41.tar.gz
輔助工具:SSH Secure Shell Client
兩台測試IP&服務器:
復制代碼 代碼如下:
Master Server: 192.168.1.2/Linux CentOS5.4/MYSQL 5.0
Slave Server: 192.168.1.3/Linux CentOS5.4/MYSQL 5.0
安裝配置步驟:
1、首先在Linux環境下分配好磁盤分區以便留足MySQL數據庫的備份空間
復制代碼 代碼如下:
[root@vps mysql]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/simfs 30G 2.0G 29G 7% /
2、MySQL數據庫的安裝:
1>將Mysql-5.0.41.tar.gz通過SSH 工具 上傳到Linux系統的home目錄下
2>建立MySQL使用者和群組:
復制代碼 代碼如下:
#groupadd mysql
#useradd -g mysql mysql
3>解壓縮Mysql-5.0.41.tar.gz源碼包
復制代碼 代碼如下:
#cd /usr/local/sofrware
#tar zxvf Mysql-5.0.41.tar.gz
4>進入源碼目錄編譯安裝
復制代碼 代碼如下:
#cd /home/Mysql-5.0.41
#./configure --prefix=/usr/local/mysql --with-charset=gbk |注:配置Mysql安裝路徑並且支持中文
#make |注:編譯
#make install |注:編譯安裝
5>替換/etc/my.cnf文件,進入源碼包,執行命令
復制代碼 代碼如下:
#cd /home/Mysql-5.0.41
#cp support-files/my-medium.cnf /etc/my.cnf
6>完成以上操作以後進行初始化數據庫,進入已經安裝好的mysql目錄
復制代碼 代碼如下:
#cd /usr/local/mysql
#bin/mysql_install_db --user=mysql |注:--user=mysql 初始化表並且規定用mysql用戶
7>設置給mysql和root用戶設定訪問權限 我們先進入mysql目錄
復制代碼 代碼如下:
#cd /usr/local/mysql
#chown -R root /usr/local/mysql 注:設定root能訪問/usr/local/mysq
#chown -R mysql /usr/local/mysql/var 注:設定mysql用戶能訪問/usr/local/mysql/var
#chgrp -R mysql /usr/local/mysql 注:設定mysql組能夠訪問/usr/local/mysq
8>啟動mysql,進入已經安裝好的目錄
復制代碼 代碼如下:
#cd /usr/local/mysql
#bin/mysqld_safe --user=mysql &
9>
修改mysql數據庫超級用戶root的缺省密碼:
復制代碼 代碼如下:
/usr/local/mysql/bin/mysqladmin -u root password 'mysql'
關閉mysql服務器
復制代碼 代碼如下:
cd /usr/local/mysql/bin
./mysqladmin -u root -p shutdown
10>設定開機就啟動mysql,進入源碼目錄下
復制代碼 代碼如下:
# cd /home/Mysql-5.0.41
# cp support-files/mysql.server /etc/init.d/mysql
# chmod +x /etc/init.d/mysql
# chkconfig --level 345 mysql on
# service mysql restart
Shutting down MySQL. [ 確定 ]
Starting MySQL [ 確定 ]
[root@localhost mysql]#
到這裡MySQL就裝好了。
3、配置MySQL5.0的復制(Replication)功能
一.將master設置為只讀。
mysql> flush tables with read lock;
二.用master中的data文件夾替換slave中的data文件夾
比如 用 tar zcvf mysql_data.gz /media/raid10/mysql/3306/data
然後 mv mysql_data.gz /media/raid10/htdocs/blog/wordpress/
因為我的 /media/raid10/htdocs/blog/wordpress/ 是 Nginx 的主目錄
所以可以在 slave上,用wget下載這個文件,然後 解壓,並覆蓋slave上的data文件
注意:覆蓋之前最好備份源文件
三.配置master的my.cnf,添加以下內容
在[mysqld]配置段添加如下字段
復制代碼 代碼如下:
server-id=1
log-bin=/media/raid10/mysql/3306/binlog/binlog //這裡寫你的binlog絕對路徑名
binlog-do-db=blog //需要同步的數據庫,如果沒有本行,即表示同步所有的數據庫
binlog-ignore-db=mysql //被忽略的數據庫
這裡給出我的my.cnf配置文件
復制代碼 代碼如下:
[client]
character-set-server = utf8
port = 3306
socket = /tmp/mysql.sock
[mysqld]
character-set-server = utf8
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-ignore-db = information_schema
user = mysql
port = 3306
socket = /tmp/mysql.sock
basedir = /usr/local/webserver/mysql
datadir = /media/raid10/mysql/3306/data
log-error = /media/raid10/mysql/3306/mysql_error.log
pid-file = /media/raid10/mysql/3306/mysql.pid
open_files_limit = 10240
back_log = 600
max_connections = 5000
max_connect_errors = 6000
table_cache = 614
external-locking = FALSE
max_allowed_packet = 16M
sort_buffer_size = 1M
join_buffer_size = 1M
thread_cache_size = 300
#thread_concurrency = 8
query_cache_size = 20M
query_cache_limit = 2M
query_cache_min_res_unit = 2k
default-storage-engine = MyISAM
thread_stack = 192K
transaction_isolation = READ-COMMITTED
tmp_table_size = 20M
max_heap_table_size = 20M
long_query_time = 3
log-slave-updates
log-bin = /media/raid10/mysql/3306/binlog/binlog
binlog-do-db=blog
binlog-ignore-db=mysql
binlog_cache_size = 4M
binlog_format = MIXED
max_binlog_cache_size = 8M
max_binlog_size = 20M
relay-log-index = /media/raid10/mysql/3306/relaylog/relaylog
relay-log-info-file = /media/raid10/mysql/3306/relaylog/relaylog
relay-log = /media/raid10/mysql/3306/relaylog/relaylog
expire_logs_days = 30
key_buffer_size = 10M
read_buffer_size = 1M
read_rnd_buffer_size = 6M
bulk_insert_buffer_size = 4M
myisam_sort_buffer_size = 8M
myisam_max_sort_file_size = 20M
myisam_repair_threads = 1
myisam_recover
interactive_timeout = 120
wait_timeout = 120
skip-name-resolve
#master-connect-retry = 10
slave-skip-errors = 1032,1062,126,1114,1146,1048,1396
#master-host = 192.168.1.2
#master-user = username
#master-password = password
#master-port = 3306
server-id = 1
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 20M
innodb_data_file_path = ibdata1:56M:autoextend
innodb_file_io_threads = 4
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M
innodb_log_file_size = 20M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
#log-slow-queries = /media/raid10/mysql/3306/slow.log
#long_query_time = 10
[mysqldump]
quick
max_allowed_packet = 32M
四.在master機上為slave機添加一同步帳號
復制代碼 代碼如下:
mysql> grant replication slave on *.* to 'admin'@'172.29.141.115' identified by '12345678';
mysql> flush privileges ;
五.配置slave的my.cnf,添加以下內容
注意:
1.如果mysql是5.5.3-m3 的版本,只需
在[mysqld]字段下添加如下內容
server-id=2
2.如果是5.0x的版本,需要
在[mysqld]字段下添加如下內容
復制代碼 代碼如下:
server-id=2
log-bin=mysql-bin //這是同步的binlog,具體以你的binlog為准
master-host=172.29.141.112
master-user=admin
master-password=12345678
master-port=3306
master-connect-retry=60 //如果發現主服務器斷線,重新連接的時間差;
replicate-do-db=blog //同步的數據庫,不寫本行 表示 同步所有數據庫
replicate-ignore-db=mysql //不需要備份的數據庫
log-slave-update
slave-skip-errors
我的mysql是5.5.3,這裡給出我的slave my.cnf配置文件
復制代碼 代碼如下:
[client]
character-set-server = utf8
port = 3306
socket = /tmp/mysql.sock
[mysqld]
character-set-server = utf8
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-do-db = blog
replicate-ignore-db = information_schema
user = mysql
port = 3306
socket = /tmp/mysql.sock
basedir = /usr/local/webserver/mysql
datadir = /media/raid10/mysql/3306/data
log-error = /media/raid10/mysql/3306/mysql_error.log
pid-file = /media/raid10/mysql/3306/mysql.pid
open_files_limit = 10240
back_log = 600
max_connections = 5000
max_connect_errors = 6000
table_cache = 614
external-locking = FALSE
max_allowed_packet = 16M
sort_buffer_size = 1M
join_buffer_size = 1M
thread_cache_size = 300
#thread_concurrency = 8
query_cache_size = 20M
query_cache_limit = 2M
query_cache_min_res_unit = 2k
default-storage-engine = MyISAM
thread_stack = 192K
transaction_isolation = READ-COMMITTED
tmp_table_size = 20M
max_heap_table_size = 20M
long_query_time = 3
log-slave-updates
log-bin = /media/raid10/mysql/3306/binlog/binlog
binlog_cache_size = 4M
binlog_format = MIXED
max_binlog_cache_size = 8M
max_binlog_size = 20M
relay-log-index = /media/raid10/mysql/3306/relaylog/relaylog
relay-log-info-file = /media/raid10/mysql/3306/relaylog/relaylog
relay-log = /media/raid10/mysql/3306/relaylog/relaylog
expire_logs_days = 30
key_buffer_size = 10M
read_buffer_size = 1M
read_rnd_buffer_size = 6M
bulk_insert_buffer_size = 4M
myisam_sort_buffer_size = 8M
myisam_max_sort_file_size = 20M
myisam_repair_threads = 1
myisam_recover
interactive_timeout = 120
wait_timeout = 120
skip-name-resolve
#master-connect-retry = 60
slave-skip-errors = 1032,1062,126,1114,1146,1048,1396
#master-host=172.29.141.112
#master-user = admin
#master-password = 12345678
#master-port = 3306
server-id = 2
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 20M
innodb_data_file_path = ibdata1:56M:autoextend
innodb_file_io_threads = 4
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M
innodb_log_file_size = 20M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
#log-slow-queries = /media/raid10/mysql/3306/slow.log
#long_query_time = 10
[mysqldump]
quick
max_allowed_packet = 32M
六.通過查看master的狀態(在master上查看),為配置slave做准備
復制代碼 代碼如下:
mysql> show master status/G;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 13
Current database: blog
*************************** 1. row ***************************
File: binlog.000005
Position: 592
Binlog_Do_DB: blog
Binlog_Ignore_DB: mysql
1 row in set (0.01 sec)
ERROR:
No query specified
從上面的信息,可以看出,master現在使用的binlog是binlog.000005,position是592,那麼下面的slave配置必須與這個對應。
其實binlog.000005是當前master使用的binlog日志文件
position是當前master使用的binlog.000005日志文件的位置
簡單理解為master正在使用哪個binlog的哪個數據行(位置)。
七.如果是5.5.3-m3版本mysql,需要啟動slave後,配置與master相關對應的信息(在slave上配置)
注意,這個與第六步相對應
復制代碼 代碼如下:
mysql> stop slave ;
mysql> change master to master_host='172.29.141.112', master_user='admin', master_password='12345678', master_log_file='binlog.000005', master_log_pos=488;
mysql> CHANGE MASTER TO MASTER_CONNECT_RETRY=60;
這個與5.0的配置my.cnf作用是一樣的,配置成與master相對應的內容
主要是配置slave,讓slave知道從master的哪個binlog上的哪個位置復制數據。所以需要知道master的ip,user_name,user_passwd,binlog,binlog_position以及多長時間連接一次master
八.開啟slave
復制代碼 代碼如下:
mysql> start slave;
九.解除master只讀限制,並做測試復制代碼 代碼如下:
mysql> unlock tables;
mysql> use blog;
mysql> create longxibendi ( a int, b int );
十.從slave上查看
復制代碼 代碼如下:
mysql> use blog;
mysql> show tables;
+-----------------------+
| Tables_in_blog |
+-----------------------+
| longxibendi |
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_terms |
| wp_usermeta |
| wp_users |
+-----------------------+
12 rows in set (0.00 sec)
可以看到成功了!!
十一.配置過程中,可以用 show slave status/G; 在 slave上
查看 slave的復制情況
十二.如果出現什麼問題,可能是防火牆的問題
/etc/init.d/iptables stop 關閉 master 上的防火牆,或者進行相應的配置
常遇到的錯誤與解決:
1.[mysql]ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
這個錯誤,網上有很多說法,其實直接的原因是mysql服務器沒有啟動
之前我按照5.0x配置master-slave,然後啟動slave,在連接slave,就會報這個錯誤
後來發現原因是,mysql slave沒有啟動起來,然後去查錯誤日志,發現以下的字段
復制代碼 代碼如下:
110505 01:55:20 mysqld_safe mysqld from pid file /media/raid10/mysql/3306/mysql.pid ended
110505 02:04:41 mysqld_safe Starting mysqld daemon with databases from /media/raid10/mysql/3306/data
InnoDB: The InnoDB memory heap is disabled
InnoDB: Mutexes and rw_locks use InnoDB's own implementation
110505 2:04:41 InnoDB: highest supported file format is Barracuda.
110505 2:04:41 InnoDB Plugin 1.0.6 started; log sequence number 44338
110505 2:04:41 [ERROR] /usr/local/webserver/mysql/libexec/mysqld: unknown variable 'master-connect-retry=60'
110505 2:04:41 [ERROR] Aborting
110505 2:04:41 InnoDB: Starting shutdown...
110505 2:04:43 InnoDB: Shutdown completed; log sequence number 44348
110505 2:04:43 [Note] /usr/local/webserver/mysql/libexec/mysqld: Shutdown complete
110505 02:04:43 mysqld_safe mysqld from pid file /media/raid10/mysql/3306/mysql.pid ended
110505 02:07:44 mysqld_safe Starting mysqld daemon with databases from /media/raid10/mysql/3306/data
InnoDB: The InnoDB memory heap is disabled
InnoDB: Mutexes and rw_locks use InnoDB's own implementation
110505 2:07:44 InnoDB: highest supported file format is Barracuda.
110505 2:07:45 InnoDB Plugin 1.0.6 started; log sequence number 44348
110505 2:07:45 [ERROR] /usr/local/webserver/mysql/libexec/mysqld: unknown variable 'master-host=172.29.141.112'
110505 2:07:45 [ERROR] Aborting
從上面的ERROR,知道 master-connect-retry=60這個my.cnf中的參數有問題,後來從網上搜資料,發現,mysql5.5.3-m3版本不支持這個參數,
然後我把這個參數注釋掉,又發現不支持這個參數master-host,從上面的ERROR字段可以看出來。後來,就知道,5.5.3-m3不能按5.0.x那樣配置
原來不需要從my.cnf中配置master相關信息,當然server-id是必須的。其他信息,通過 在命令行中 ,登陸 mysql服務器配置。
其實server-id的作用是
第一,標識,區分不同的slave,第二,防止環備份的發生
2.Last_Error: Last_SQL_Error:等錯誤
這個是從 slave上,運行 show slave status/G; 得到的。出現這個問題,最根本的原因是,slave 沒有與當前的master的binlog 和binlog的position對應上
也就是說,slave傳輸的master binlog 不與當前master正使用的binlog以及binlog的行數對應。
3.[ERROR] Slave I/O: error connecting to master '[email protected]:3306' - retry-time: 60 retries: 86400, Error_code: 2003
這個就是因為防火牆的問題,所以用 /etc/init.d/iptables stop 關閉防火牆就OK了。
4.遇到ERROR 2013 (HY000): Lost connection to MySQL server during query錯誤。
在/ect/my.cnf的[mysqld]中添加skip-name-resolve