mysqlAB複製 mysql主從複製有利於數據庫的健壯性、提高訪問速度和易於維護管理。 總結: 從庫上配置帳戶、ip、用戶名、密碼、連接文件的位置、pos點,在從庫上同步數據前要把主庫以前的數據導入到從庫,而後在實行數據同步。 開啓開關以前,主從庫數據要一致 在打開開關以前要在主庫上創建受權,連接從庫的帳號 主庫必需要打開bin-log開關 要啓動 start slave;來開始同步 dns主-----> dns從 非實時 mysql主------------------> mysql從 實時 延時是很嚴重的問題 mysql replication mysql AB 複製技術(主從) 原理很是相似 oracle dataguard oracle DG (dataguard) MySQL支持單向、異步複製,複製過程當中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。 同步複製須要使用ndb(各集羣節點均可讀可寫)或者drbd(網絡raid)這些技術,或者是新版mysql的半同步複製 異步 優勢:主速度快 缺點:數據可能主從不一樣步 同步 優勢和缺點和異步正好相反 mysql主 ----------> mysql從 create table aaa; bin-log --------> relay-bin-log io sql create table aaa; 把主上的二進制日誌(bin-log)的內容傳到從上的一個新的日誌叫relay-bin-log 從上的 IO 線程 負責傳輸 從上的 SQL 線程 負責從服務器解析日誌 由兩個線程 去進行復制的過程 IO線程 sql線程 (之前只使用一個線程,兩個是改進後纔有的) 複製的過程: 1,slave端的IO線程連上master端,請求 2,master端返回給slave端,bin log文件名和位置信息 3,IO線程把master端的bin log內容依次寫到slave端relay bin log裏,並把master端的bin-log文件名和位置記錄到master.info裏。 4,salve端的sql線程,檢測到relay bin log中內容更新,就會解析relay log裏更新的內容,並執行這些操做;也就是說salve執行和master同樣的操做而達到數據同步的目的; ============================================================================= AB複製前準備 1,準備兩臺機器 2,安裝兩臺全新的mysql(這裏使用rpm版,方便,源碼版能夠課後自行作測試;兩臺版本最好一致,不一致可能會有兼容性問題) yum -y install mysql* 3,主機名配置及其綁定(兩臺互相綁定) vim /etc/hosts (主機名和ip相互綁定只綁本身的) 4,時間同步 5,防火牆,selinux關閉 準備兩臺虛擬機:最好是全新 master ---- slave 172.16.14.2 172.16.14.3 第一步;改配置文件,並重啓服務 # vim /etc/my.cnf master上 (主文件) [mysqld] log-bin=mysql-bin 二進制日誌必須打開 server-id=2 slave上 (副文件) [mysqld] server-id=3 /etc/init.d/mysqld restart 用腳本重啓 第二步:主受權 在主文名字是主到 ip寫從到 master上受權,super和replication slave都是複製要用的權限 mysql> grant super,replication slave on *.* to 'li'@'172.16.14.X' identified by '123'; 在主受權給從的ip地址,讓他以主到身份登陸 li表明的是主機名 mysql> flush privileges; 第三步:查看master的正在寫的二進制文件名和位置 mysql> show master status; --只有打開二進制日誌,這句命令纔有結果,表示當前數據庫的二進制日誌寫到什麼位置 +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000003 | 473 | | | +------------------+----------+--------------+------------------+ 第四步:在slave(從)上鍊接master(主),並指定從哪一個position開始複製 在(從端操做)下面 mysql> change master to -> master_user='li', --對應前面主受權時的用戶 -> master_password='123', --對應前面主受權時的密碼 -> master_host='172.16.14.2', --主的IP -> master_port=3306, --端口,若是爲3307就要換成3307 -> master_log_file='mysql-bin.000003', --主上面查到的文件名 -> master_log_pos=473; --主上面查到的位置號 這部報錯的話把stop slave; 切記必須關掉以後在修改,而後啓動 mysql> start slave; mysql> show slave status\G 查看錶 ...... Slave_IO_Running: Yes Slave_SQL_Running: Yes --這兩人個線程爲yes,表明集羣搭建成功 ...... ============================================================================= 問題一: 思考幾種狀況下作複製的區別: 1, 業務尚未上線的狀況,全新安裝的mysql作複製 2,主已經跑了一年,一直都有開着二進制日誌,而且日誌無丟失 直接從一年前的起始位置開始複製(但要注意初始化的數據不要重複初始化的數據) 3,主已經跑了一年,但沒有打開二進制日誌 驟一:master打開二進制日誌,重啓 步驟二:master全備,並恢復到slave(假設要30分鐘) 步驟三;30分鐘後,slave從備份的position開始複製 4, 主之前跑了半年沒打開二進制日誌,後半年打開了二進制日誌,你如今要作從 驟一:master全備,並恢復到slave(假設要30分鐘) 步驟二;30分鐘後,slave從備份的position開始複製 主 從 .000001 1 跑了一年 跑了一年的數據 如今 .000054 563 563 備份恢復 30分鐘 .000054 800 問題二: 主要打開二進制日誌,從要不要開二進制日誌? 從mysql可開可不開,要看狀況 問題三: 主和從的讀寫狀況怎麼作? 從不能寫,從只能讀;主可讀可寫; 因此有些時候作主只寫,從只讀,也就是讀寫分離 問題四: 我作了讀寫分離的一主一從的架構,請問我前端的程序(web,遊戲,業務等)如何來訪問數據庫? 若是裝前端web(假設phpwind),填寫數據庫的IP爲主的IP,那麼這種狀況, mysql從就徹底變成了一個實時備份的服務器,全部的讀寫全在主上 因此要在前端程序和數據庫之間加入代理層程序,也就是填寫的數據庫IP不是主的也不是從的, 而是代理的,由代理來負責把寫操做給主,讀操做給從 客戶 | | web程序,遊戲程序(c,php,java.......) | | 代理層(中間件)(mysqlproxy,amoeba,cobar,mycat) | | mysql主 ----> mysql從 問題五: 關於單點故障的問題,若是從掛掉了,怎麼解決?若是主掛掉了,怎麼解決? 從掛掉,再恢復的過程圖: 代理 mysql主 ----> mysql從 寫 讀 從掛了 寫讀 好久以後,從要啓動,啓動以前能夠手動寫防火牆,讓代理訪問不到從 啓動,會自動連主,主會把這段時間寫的複製給從 複製完後,手動確認(能夠在從啓動前在主上show master status;查看主寫到哪了.而後在從上能夠show slave status查看寫到主的postion或者這個positsion以後,則表示數據都複製過來了),而後去掉防火牆 代理髮現從OK了,會把讀給從 寫 讀 主掛掉,再恢復的過程圖:(這樣最好作雙主,右邊的主平時正常狀況而後作只讀的從,只在左邊的主掛了,纔會作寫操做) 代理 mysql主 <----> mysql從(打開二進制日誌) 寫 讀 主掛了 寫 讀 好久以後,主要啓動,啓動以前手動寫防火牆,讓代理訪問不到主 主啓動,自動連上後,由於是雙主,從能夠把這段時間寫的複製回主 複製完後,手動確認,而後去掉主上的防火牆 代理髮現主OK了,會把寫給回主 寫 讀 ============================================================================= 一主一從 關於另幾種架構的探討: 一主多從 -- salve master -- salve -- salve --適合於以讀爲主的業務,使用多個salve分擔讀的壓力,但要注意的是這種架構,salve越多,那麼master複製的壓力就越大(成本增大) 多主一從 --這種架構不支持 主A phpwind 從C 主B discuz 雙主架構 master A <--> master B phpwind主 discuz主 上面已經討論了雙主架構的一個用法(就是一個平時仍然爲主,另外一個平時爲從,只在主掛了纔會去從上寫) 1,會循環複製嗎? 他們不會循環複製,由於作複製時會指定ID值,而且不一致 2,兩邊真的能同時寫相同的數據嗎? 可能會有問題 以下表所示: 時間點 master A master B 1 id=1改成id=2 2 id=1改成id=3 3 master A的改變複製過來,並解析,id會又改成2 4 master B的改變複製過來並解析,id又會改成3 問題產生,數據不一致 3,兩邊能夠寫不一樣的數據嗎? 能夠 能夠經過業務程序層,指定一些表的寫操做全在一端,另外一些表的寫操做全在另外一端,也就是說兩邊不會同時寫相同的表(固然這是理想狀態,由於業務複雜的話會有表的聯結等狀況) 而後經過指定mysql複製的參數,一部分表或庫會從A複製到B,另一部分表或庫從B複製到A就能夠避免上面的問題了 或者兩個庫,一個庫master A來寫,另外一個庫master B來寫 數據切分 ------------------------------------------------------ master C | | 環型架構 master A -- master B --不可行 ------------------------------------------------------ -- salve 級聯架構 master -- salve -- salve -- salve 爲了解決一主多從的master的複製壓力 能夠把slave作爲下一級從機的master 增長複製的級聯層次,形成的延遲更長 因此這種架構並非很推薦,通常會進行分拆集羣 -------------------------------------------------- 雙主和級聯合起來 master ----salve --slave | | -- slave master ---salve -- slave -- slave ----------------------------------------------------- 優化原則:分 大型結構的數據量太大,要用到數據切分(水平,垂直) mysqlproxy amoeba cobar ============================================================================= 一主多從的作法 就是上面的步驟有幾個從就作幾回 雙主架構的作法: 反着作一遍就行 級聯架構 master -slave -slave 個人結構圖 master A slave B slave C 172.16.14.2 172.16.14.3 172.16.14.4 sever-id=2 server-id=3 server-id=4 log-bin=master log-bin=mid-slave log-slave-updates=1 bin-log relay-bin-log relay-bin-log bin-log ------> relay-bin-log 打開log-slave-updates=1 讓第一臺傳過來relay日誌記錄 到本身的二進制日誌 bin-log -------> relay-bin-log 練習: 實現下面的結構圖(這裏包括了一主一從,一主多從,雙主,級聯架構) mysql1 《----》 mysql2 ----》 mysql3 ============================================================================= 半同步複製 MySQL的默認複製實際上是異步操做,而不是同步,也就意味着容許主從之間的數據存在一 定的延遲,mysql當初這樣設計的目的也是基於可用性的考慮,爲了保證master 不受slave的影響,而且異步複製使得master處於一種性能最優的狀態: 寫完binlog後便可提交而不須要等待slave的操做完成。這樣存在一個隱患,當你使用slave做爲備份時 若是master掛掉,那麼會存在部分已提交的事務未能成功傳輸到slave的可能,這就意味着數據丟失! mysql 主 ---- mysql從 所謂的半同步複製就是master每commit一個事務,要slave應用這個事物後回給master信號。這樣master才能把事物成功commit。這樣就保證了master-slave的數據絕對的一致(可是以犧牲master的性能爲代價).但等待時間也是能夠調整的。 mysql半同步複製等待時間超時後(默認時間爲10秒),會自動轉換成異步複製 ========================================= 搭建環境 兩臺虛擬機 master -- slave 先安裝mysql5.5以後的版本,由於這個版本以後才實現的半同步複製 第一大步: 先要搭建好mysqlAB異步複製 過程省略 第二大步:在異步基礎上轉成半同步複製 1,在master上安裝這個插件 master> install plugin rpl_semi_sync_master soname 'semisync_master.so'; Query OK, 0 rows affected (0.00 sec) --刪除插件的方法 mysql > uninstall plugin rpl_semi_sync_master; master> show global variables like 'rpl_semi_sync%'; --安裝OK後,主上會多幾個參數 +------------------------------------+-------+ | Variable_name | Value | +------------------------------------+-------+ | rpl_semi_sync_master_enabled | OFF | --是否啓用master的半同步複製 | rpl_semi_sync_master_timeout | 10000 | --默認主等待從返回信息的超時間時間,10秒。 | rpl_semi_sync_master_trace_level | 32 | --監控 | rpl_semi_sync_master_wait_no_slave | ON | --是否容許每一個事物的提交都要等待slave的信號.on爲每個事物都等待 +------------------------------------+-------+ 2,在slave上安裝插件 slave> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; Query OK, 0 rows affected (0.03 sec) slave> show global variables like 'rpl_semi_sync%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | rpl_semi_sync_slave_enabled | OFF | | rpl_semi_sync_slave_trace_level | 32 | +---------------------------------+-------+ 3,master上激活半同步複製 master> set global rpl_semi_sync_master_enabled =on; Query OK, 0 rows affected (0.00 sec) 4,slave上激活半同步複製 slave> set global rpl_semi_sync_slave_enabled=on; slave> stop slave IO_THREAD; slave> start slave IO_THREAD; 5,在master查看狀態 master > show global status like 'rpl_semi_sync%'; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 1 | --有一個從服務器啓用半同步複製 | Rpl_semi_sync_master_net_avg_wait_time | 0 | --master等待slave回覆的平均等待時間。單位毫秒 | Rpl_semi_sync_master_net_wait_time | 0 | --master總的等待時間。單位毫秒 | Rpl_semi_sync_master_net_waits | 0 | --master等待slave回覆的總的等待次數 | Rpl_semi_sync_master_no_times | 0 | --master關閉半同步複製的次數 | Rpl_semi_sync_master_no_tx | 0 | --master 等待超時的次數 | Rpl_semi_sync_master_status | ON | --標記master如今是不是半同步複製狀態 | Rpl_semi_sync_master_timefunc_failures | 0 | --master調用時間(如gettimeofday())失敗的次數 | Rpl_semi_sync_master_tx_avg_wait_time | 0 | --master花在每一個事務上的平均等待時間 | Rpl_semi_sync_master_tx_wait_time | 0 | --master花在事物上總的等待時間 | Rpl_semi_sync_master_tx_waits | 0 | --master事物等待次數 | Rpl_semi_sync_master_wait_pos_backtraverse | 0 | --後來的先到了,而先來的尚未到的次數 | Rpl_semi_sync_master_wait_sessions | 0 | --當前有多少個session由於slave回覆而形成等待 | Rpl_semi_sync_master_yes_tx | 0 | --標記slave是否在半同步狀態 +--------------------------------------------+-------+ 6,在slave上查看狀態就只有下面一條信息 slave > show global status like 'rpl_semi_sync%'; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Rpl_semi_sync_slave_status | ON | +----------------------------+-------+ 第三大步 測試: master > insert into a values (3); Query OK, 1 row affected (0.01 sec) master > show global status like 'rpl_semi_sync%_yes_tx'; +-----------------------------+-------+ | Variable_name | Value | +-----------------------------+-------+ | Rpl_semi_sync_master_yes_tx | 1 | --表示此次事物成功從slave返回一次確認信號 +-----------------------------+-------+ 模擬錯誤,把slave上的mysql停掉 --再回到master上測試 master> insert into a values (4); Query OK, 1 row affected (10.00 sec) --此次插入一個值須要等待10秒(默認的等待時間) master> insert into a values (5); Query OK, 1 row affected (0.01 sec) --如今自動轉成了原來的異步模式(相似oracle DG裏的最大性能模式) 再次把slave啓動,看到半同步複製沒啓來,是異步模式 從新按下面的步驟把同步模式再啓起來就能夠了 slave> set global rpl_semi_sync_slave_enabled=on; slave> stop slave IO_THREAD; slave> start slave IO_THREAD; slave啓起來後,查看錶,發現剛纔slave關閉期間的那幾條數據仍是會自動複製過來,數據又回到一致 ===================================================================== mysql的延時複製(IO線程是實時,只是把SQL線程延時了) 異步或同步複製 A ----------> B | |-------> C 延時1天 誤刪除一張用了好幾年的數據表 恢復方法: 1,經過每週的備份來恢復(假設週一0點全備,週三誤刪除) 先恢復週一的全備到測試庫上,而後再恢復全備到如今的二進制日誌(除了誤刪除的那句),再把那張表導出來,導回到生產庫上 2,徹底經過二進制日誌來恢復 須要把這幾年內全部的二進制日誌先合併,再經過sed,grep,awk等把這張表從建表到如今的全部操做按順序找出來(固然要除掉你最後誤刪除的那條),而後應用回去 3,有延時複製的話,在C上導出這張表,導回A mysql開源管理工具 軟件路徑在 筆記目錄下/mysql/mysql_soft/maatkit-7540.tar.gz --在mysql AB的slave上安裝(只須要在slave上安裝,包含下面的步驟都是在slave上作的) # tar xf maatkit-7540.tar.gz -C /usr/src/ # cd /usr/src/maatkit-7540/ 安裝方法README文件裏有寫 # perl Makefile.PL --若是不成功,須要安裝perl有關的多個包,能夠yum install perl* # make install # ls bin/ --這些命令,就是各個管理工具 mk-archiver mk-purge-logs mk-checksum-filter mk-query-advisor mk-config-diff mk-query-digest mk-deadlock-logger mk-query-profiler mk-duplicate-key-checker mk-show-grants mk-error-log mk-slave-delay mk-fifo-split mk-slave-find mk-find mk-slave-move mk-heartbeat mk-slave-prefetch mk-index-usage mk-slave-restart mk-kill mk-table-checksum mk-loadavg mk-table-sync mk-log-player mk-table-usage mk-merge-mqd-results mk-tcp-model mk-parallel-dump mk-upgrade mk-parallel-restore mk-variable-advisor mk-profile-compact mk-visual-explain --使用--help查看一個命令的使用方法 # mk-slave-delay --help mk-slave-delay starts and stops a slave server as needed to make it lag behind the master. The SLAVE-HOST and MASTER-HOST use DSN syntax, and values are copied from the SLAVE-HOST to the MASTER-HOST if omitted. For more details, please use the --help option, or try 'perldoc /usr/bin/mk-slave-delay' for complete documentation. --mysql AB(不管同步或異步)正在運行OK的狀況下,使用下面的命令在slave上運行;作之間建議把時間同步一下 # mk-slave-delay --defaults-file=/etc/my.cnf --delay=1m --interval=15s --user=root --password=123 --quiet localhost & --表示延時1分鐘,纔會應用SQL線程;這裏是測試因此才使用很小的時間,實際狀況能夠調成1小時或2小時 測試: 在master上隨便插入幾條數據 而後在slave上發現沒有立刻同步過來 slave > show slave status\G; --查看狀態會發現SQL線程狀態爲NO Slave_IO_Running: Yes Slave_SQL_Running: NO 大概等1分鐘,就會自動延時同步過來了; --注意:日誌已經傳到slave的relay-bin log裏了,但由SQL線程延時去解析