MYSQL的高級知識及AB複製

慢查詢日誌(slow query log)

mysql> show variables like '%log_slow%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| log_slow_queries | OFF   |是否打開slow query log功能,打開slow query log功能對系統性能的整體影響沒有binlog那麼大,畢竟slow query log的
+------------------+-------+數據量比較小,帶來的IO損耗也就較小,但消耗總是會有一些的,主要是CPU方面的消耗。如果大家的系統CPU資源足夠豐富,可以不必在乎這一點點損耗,畢竟它可能會帶來更大性能優化方面的收穫。但如果CPU資源比較緊張,完全可以在大部分時候關閉此功能,只須要間斷性地打開此功能來定位可能存在的慢查詢


mysql> show variables like '%long_query%%';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| long_query_time | 10    | 系統需要記錄執行時間超過多長的query
+-----------------+-------+


[root@li ~]# vim /usr/local/mysql/etc/my.cnf

log_slow_queries=/var/log/mysqld/mysql55_lamp-slow.log
long_query_time=3

 

 

 

  Query Cache優化
query cache的原理:簡單來說就是將客戶端請求的query語句(僅限select類型的query)通過一定的hash算法進行一個計算,得到一個hash值,存放在一個hash桶中。同時將該query的結果集(Result Set)也存放在一個內存cache中。存放query hash值的鏈表中每一個hash值所在節點的同時,還存放了該query所對應的Result Set的Cache所在的內存地址,以及該query涉及的所有table的標識等一些其他相關信息。系統接受到任何一個select類型的query時,首先計算出其hash值,然後通過該hash值到query cache中去匹配,如果找到了完全相同的query,則直接將之前所緩存(cache)Result set返回給客戶端,完全不須要進行後面的任何步驟就可完成這次請求。而後端的任何一個表的任何一條數據發生變化之後,也會通知Query cache,須要將所有與該table有關的query的cache全部失效,並釋放出之前佔用的內存地址,以便後面其他的Query能夠使用。
   query cache的負面影響
 1。query語句的hash運算及hash查找資源消耗。雖然hash運算和查找的過程也已經足夠的優化了,對於一條query來說消耗的資源確實是非常之少,但是當每秒都有上千甚至幾千條query時,就不能對產生的cpu消耗完全忽視了。
 2。query cache的失效問題。如果表的變更比較頻繁,則會造成query cache的失效率非常高,表中數據,結構,或索引等的任何變更都會造成將緩存到query cache中的cache數據被清除,導致新的相同query進來後無法使用到之前的cache。
 3。query cache中緩存的是Result Set,而不是數據頁,也就是說,存在同一條記錄被cache多次的可能性,從而造成內存資源的過渡消耗。

 

   使用query cache
 首先,須判斷哪些表適合使用query cache;避免在查詢變化頻繁的table的query上使用,而應該在那些查詢變化頻率較低的table的query上使用。mysql中針對query cache有兩個專用的SQL Hint(提示):SQL_NO_CACHE和SQL_CACHE,分別代表強制不使用query cache和強制使用query cache.對於那些變化非常少,大部分時候都是靜態的數據,可以添加SQL_CACHE的SQL Hint,強制Mysql使用QUERY cache,從而提高該表的查詢性能。
 
mysql> show variables like '%query_cache%';
+------------------------------+---------+
| Variable_name                | Value   |
+------------------------------+---------+
| have_query_cache             | YES     | mysql是否支持query_cache
| query_cache_limit            | 1048576 | query cache存放的單條query最大Result Set,默認1MB
| query_cache_min_res_unit     | 4096    | 每個result set存放的最小內存大小,默認4KB;
| query_cache_size             | 0       | query_cache_size系統用於query cache內存的大小
| query_cache_type             | ON      | 系統是否打開了query cache功能
| query_cache_wlock_invalidate | OFF     | 針對於MYISAM存儲引擎,設置當有WRITE LOCK在某個table上時,讀請求是要等write lock釋放資源後再查詢還是允許從query cache中讀取結果,默認爲FALSE(可以直接從Query cache中取得結果)


mysql> set global query_cache_size=1024*1024*10;  --設置爲10M

 

vim /usr/local/mysql/etc/my.cnf

query_cache_size=10M  --定義query_cache的大小爲10M
query_cache_type=1  

/etc/init.d/mysql5  restart

mysql> show variables like '%query_cache%';
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| have_query_cache             | YES      |
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 10485760 |  --再次查看,這裏就有10M的大小
| query_cache_type             | ON       |
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+

 

  獲取Query Cache相關的狀態變量

mysql> show status like '%Qcache%';

| Variable_name           | Value |
+-------------------------+-------+
| Qcache_free_blocks      | 0     | query cache中目前還有多少多餘的blocks。如果該值顯示較大,則說明內存碎片過多,要找合適機會整理。
| Qcache_free_memory      | 0     | query cache中目前剩餘的內存大小
| Qcache_hits             | 0     | 多少次命中
| Qcache_inserts          | 0     | 多少次未命中然後插入 命中率=Qcache_hits/(Qcache_hits+Qcache_inserts);
| Qcache_lowmem_prunes    | 0     | 多少條query因爲內存不足而被清除出query cache
| Qcache_not_cached       | 0     | 因爲query_cache_type的設置而不能被緩存cache的query數量,或者是超過了query_cache_limit的單個結果集的設置
| Qcache_queries_in_cache | 0     | 當前query cache中緩存的query數量
| Qcache_total_blocks     | 0     | 當前query cache中的block總數量
+-------------------------+-------+

 

mysql> create table aaa (id int,name varchar(20));
Query OK, 0 rows affected (0.01 sec)

mysql> insert into aaa values('1','sfdasdf');
Query OK, 1 row affected (0.01 sec)

mysql> insert into aaa select * from aaa;

.........

mysql> insert into aaa select * from aaa;
Query OK, 524288 rows affected (5.36 sec)
Records: 524288  Duplicates: 0  Warnings: 0

mysql> show status like '%Qcache%'; --先查看一下狀態

mysql> select * from aaa; --這樣查看這個一百多W行的大表

mysql> show status like '%Qcache%'; --可以看到並沒有cache,Qcache_not_cached增加了,說明應該是結果集超出了範圍不能cache

mysql> select * from aaa limit 10; 


mysql> show status like '%Qcache%'; --可以看到 Qcache_inserts 增加1,並且Qcache_queries_in_cache也增加1


mysql> select * from aaa limit 10;  

mysql> show status like '%Qcache%';  --可以看到這次只有Qcache_hits增加1

mysql> select * FROM aaa limit 10;  --這次把from換成大寫,結果是一樣的,SQL語句的關鍵字是不區分大小寫的

mysql> show status like '%Qcache%';  --可以看到 Qcache_inserts 增加1,並且Qcache_queries_in_cache也增加1;說明語句需要完全一致再能命中query cache


小實驗:驗證query cache加快查詢速度

mysql> set global query_cache_size=1024*1024*100;  --設大點
Query OK, 0 rows affected (0.00 sec)

mysql> set global query_cache_limit=1024*1024*80; --設大點
Query OK, 0 rows affected (0.00 sec)

mysql> show status like '%Qcache%';  --重設過query cache,那麼以前緩存的被清0,但命中次數等還是老數據

mysql> select * from aaa; --查100多W行需要1.5秒左右


mysql> show status like '%Qcache%';  --可以看到剛纔的語句被緩存,說明把緩存限制調大能存放這100多W行

mysql> select * from aaa;   --現在只需要大概0.25秒左右;說明query cache裏取結果是加快了查詢速度

mysql> show status like '%Qcache%';  --確認是命中了

 

============================================================

 

 table cache相關的優化
  爲了提高性能,在mysql中每個線程都是獨立地打開自己需要的表的文件描述符,而不是通過共享已經打開的表的文件描述符的。當然,針對不同的存儲引擎可能有不同的處理方式。如myisam表,每一個客戶端線程打開任何一個myisam表的數據文件都須要打開一個文件描述符,但如果是索引文件,則可以多個線程共享同一個索引文件的描述符;對於innoDB的存儲引擎,如果使用的是共享表空間來存儲數據,那麼須要打開的文件描述符就比較少,而如果使用的是獨享表空間方式來存儲數據,由於存儲表數據的數據文件較多,則同樣會打開很多的表文件描述符。

mysql> show variables like 'table_cache';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| table_cache   | 64    | 當前系統設置的table_cache爲64個,也就是說該mysql中,table cache內可以緩存64個打開文件的描述符,但也不是越高越好,設置得太高,可能會造成文件描述符不足,從而造成性能不穩定或者連接失敗
+---------------+-------+

mysql> show status like '%open%tables%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Com_show_open_tables   | 0     |
| Open_tables            | 5     |  --當前系統中正打開的描述符有5個,如果在峯值時間open_tables等於table_cache的值,opened_tables也在不斷增大,且內存夠的情況下要考慮增大table_cache
| Opened_tables          | 0     |

 

mysql> flush table; --此命令會關閉當前table cache中緩存的所有文件描述符
Query OK, 0 rows affected (0.00 sec)

mysql> show status like 'open_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 0     | flush table後,就可以看到正打開的描述符爲0了
+---------------+-------+

 


--------------------------------------------------------------
--以下是mysql5.5.X版有關的參數和定義
mysql> show variables like 'table%cache';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| table_definition_cache | 256   | # 表定義緩存,建議比實際的表的數量大
| table_open_cache       | 64    | # 表數據文件描述符號緩存。
+------------------------+-------+

table_open_cache 表數據文件描述符號緩存。
 table_open_cache = max_connections * N ;
  N 代表單個query語句中涉及到的表的數量。
  或者直接把N數值設定爲2-3倍。設定大不影響。

 


通過狀態數據判斷設定是否適當
mysql> show status like 'open%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| Open_files               | 21    | 打開過多少個文件
| Open_streams             | 0     |
| Open_table_definitions   | 15    | 打開過15個表定義文件
| Open_tables              | 9     | 打開過9個表
| Opened_files             | 66    | 
| Opened_table_definitions | 1     | 正在打開一個表定義
| Opened_tables            | 1     | 正在打開一個表
+--------------------------+-------+

 

擴展一個面試題:

 apache使用access_log來記錄訪問日誌


 請問:如果我現在mv access_log access_log.bak後,再來的訪問是記錄到哪裏(apache重啓或沒有重啓分別會是什麼情況)

 

------------------------------------------------------------


  mysql server其他常用優化
 網絡連接與連接線程
  max_connections 整個MYSQL允許的最大連接數,一般來說500到800左右是一個比較合適的參考值
  
  net_buffer_length 網絡包傳輸中,傳輸消息之前的net buffer初始化大小
  max_allowed_packet 在網絡傳輸中,一次消息傳輸量的最大值
  back_log  在MYSQL的連接請求等待隊列允許存放的最大連接請求數


max_connections
 mysql最多可以同時連接多少個(併發量),對於那些比較繁忙,併發量比較大的,可以設置500-800。
 lotp 類型(在線事務處理,例如:bbs網站),屬於短連接,應該設定大一點
 對於數據倉庫,一般連接之後,很久才斷開,數據長連接,應該設置少一點

mysql> show status like '%connections%';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Connections          | 2     | mysql啓動以來接受多少個連接
| Max_used_connections | 1     | 有史以來最大同時連接的峯值
+----------------------+-------+


  thread_cache_size thread cache 池中應該存放的連接線程數,應用程序使用的是短連接,功效最明顯,如果是長連接,設置50~100
  thread_stack  每個連接線程被創建時,MYSQL給它分配的內存大小


mysql> show variables like 'thread%';
+-------------------+--------+
| Variable_name     | Value  |
+-------------------+--------+
| thread_cache_size | 50     | 能緩存50個連接數
| thread_stack      | 196608 | 每個連接線程被創建時,mysql給它分配的內存大小
+-------------------+--------+


 連接線程池thread_cache

mysql> show variables like 'thread%';
+-------------------+---------------------------+
| Variable_name     | Value                     |
+-------------------+---------------------------+
| thread_cache_size | 0                         |
| thread_handling   | one-thread-per-connection |
| thread_stack      | 196608                    |
+-------------------+---------------------------+

thread_cache_size  <--連接線程池可以保存多少個空閒線程,0關閉。可以設定一個具體的數值,一般建議50-100.要具體情況設定。
thread_stack  每個線程創建的時候,分配多少的初始化內存給該線程,默認192KB
 


mysql> show status like 'connections';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Connections   | 30    | 系統被連接的次數(注意是次數,不是當前連接數)
+---------------+-------+
1 row in set (0.00 sec)

 

mysql> show status like '%thread%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Delayed_insert_threads | 0     |
| Slow_launch_threads    | 0     |
| Threads_cached         | 3     |  thread cache池中共緩存了3個連接線程
| Threads_connected      | 5     |  當前有5個連接線程處於和客戶端連接的狀態
| Threads_created        | 8     |  共創建了8個連接線程
| Threads_running        | 1     |  只有一個連接線程正在處理客戶端提交的請求
+------------------------+-------+


Sort Buffer,Join Buffer 和 Read Buffer

mysql> show variables like '%buffer%';
+-------------------------------+---------+
| Variable_name                 | Value   |
+-------------------------------+---------+
| bdb_log_buffer_size           | 32768   |
| bulk_insert_buffer_size       | 8388608 |
| innodb_buffer_pool_awe_mem_mb | 0       |
| innodb_buffer_pool_size       | 8388608 |
| innodb_log_buffer_size        | 1048576 |
| join_buffer_size              | 131072  | 只有當join是all,index,rang,或者index_merge時使用到join buffer,這種join被稱爲Full join.
| key_buffer_size               | 8388600 |
| myisam_sort_buffer_size       | 8388608 | 增大此參數來提高order by或者group by的處理性能,系統默認大小爲2MB,最大限制和join buffer一樣爲
| net_buffer_length             | 16384   | 4G,但在除了windows之外的64位的平臺上可以超出4G的限制
| preload_buffer_size           | 32768   |
| read_buffer_size              | 131072  |
| read_rnd_buffer_size          | 262144  |
| sort_buffer_size              | 2097144 | --默認2M,在有大量排序的服務器上可以考慮增大幾M
+-------------------------------+---------+

 


============================

二、針對MyISAM的優化
 主要集中於索引的優化。

mysql> show variables like 'key%';
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| key_buffer_size          | 8384512 |
| key_cache_age_threshold  | 300     |
| key_cache_block_size     | 1024    |
| key_cache_division_limit | 100     |
+--------------------------+---------+

key_buffer_size 默認是8M作爲索引緩存區的容量

key_cache_block_size 內存塊大小,索引文件是一塊一塊被mysql緩存。

索引數據的分類:
 熱點數據hot sub-chain和普通數據 warm sub-chain

key_cache_division_limit  默認是100,代表不去區別熱點數據,直接把key_buffer的所有容量保存普通索引數據緩存。如果是70,那麼代表將會使用30%的key_buffer內存空間作爲熱點數據hot sub-chain保存容量。

key_cache_age_threshold
 數值越小,熱點數據更容易被降級爲普通數據。


mysql> show status like 'key_%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Key_blocks_not_flushed | 0     | 
| Key_blocks_unused      | 7245  |
| Key_blocks_used        | 0     |
| Key_read_requests      | 0     |
| Key_reads              | 0     |
| Key_write_requests     | 0     |
| Key_writes             | 0     |
+------------------------+-------+

Key_blocks_not_flushed
 有多少個修改過索引數據塊(骯髒數據)還沒被刷新到索引文件中。
 注意:如果在對索引文件進行熱拷貝,那麼該值必須0

Key_blocks_unused 空閒的key_buffer空間

Key_read_requests  key_buffer讀請求命中了多少次
Key_reads key_buufer未命中而導致需要從磁盤文件中加載索引數據到內存中
Key_write_requests key_buffer寫請求命中了多少次
Key_writes  key_buufer未命中而導致需要從磁盤文件中加載索引數據到內存中才開始對數據進行修改


通過計算命中率,測量設定是否正確:
 讀命中率= Key_read_requests/(Key_read_requests+Key_reads)*100
  命中律應該95%以上

 使用百分比=Key_blocks_used/(Key_blocks_used+Key_blocks_unused)
  應該是99-100% 

可以把key_buffer自定義分成多個區域,一般我們自己分,分爲:
 hot_area,cold_area,剩下的就是mysql默認存放其他索引數據
 hot_area,cold_area名字是自定義,只不過這裏爲了聲明自定義內存區域的一個典型的用途。


1、設定總的key_buffer容量
mysql> set global key_buffer_size=16*1024*1024;
2、設定關鍵緩存(自定義區域)
 1)分配6M的空間作爲自定義熱點數據存放空間
mysql> set global hot_area.key_buffer_size=6*1024*1024;
 
 2)分類2M作爲冷數據....
mysql> set global cold_area.key_buffer_size=2*1024*1024;

 說明剩下的8M內存空間作爲普通的索引數據緩存空間

3、定義哪些表的索引數據存放哪些區域裏。

假設用於存放帖子的pw_threads表,訪問熱度很高,就應該存放hot_area
mysql> cache index bbs.pw_threads in hot_area;
+----------------+--------------------+----------+----------+
| Table          | Op                 | Msg_type | Msg_text |
+----------------+--------------------+----------+----------+
| bbs.pw_threads | assign_to_keycache | status   | OK       |
+----------------+--------------------+----------+----------+

 

假設pw_help表訪問熱度很低,但索引數據很龐大,就應該放在cold_area,保證它不根別的索引數據搶空間。

mysql> cache index bbs.pw_help in cold_area;
+-------------+--------------------+----------+----------+
| Table       | Op                 | Msg_type | Msg_text |
+-------------+--------------------+----------+----------+
| bbs.pw_help | assign_to_keycache | status   | OK       |
+-------------+--------------------+----------+----------+

4、根據上面步驟的定義 ,把相應的索引數據進行裝載。

mysql> load index into cache bbs.pw_threads,bbs.pw_help ignore leaves;
+----------------+--------------+----------+----------+
| Table          | Op           | Msg_type | Msg_text |
+----------------+--------------+----------+----------+
| bbs.pw_threads | preload_keys | status   | OK       |
| bbs.pw_help    | preload_keys | status   | OK       |
+----------------+--------------+----------+----------+

 

 


===============================================================


mysql AB 複製技術


MySQL支持單向、異步複製,複製過程中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。

同步複製需要使用ndb或者drbd這些技術

 

       打開bin-log  
  master   - slave
  可讀可寫 一般只可讀

 由兩個線程  去進行復制的過程   IO線程     sql線程 (以前只使用一個線程,兩個是改進後纔有的)

複製的過程:
 1,slave端的IO線程連上master端,請求

 2,master端返回給slave端,bin log文件名和位置信息

 3,IO線程把master端的bin log內容依次寫到slave端relay log裏,並把master端的bin-log文件名和位置記錄到master.info裏。

 4,salve端的sql線程,檢測到relay log中內容更新,就會解析relay log裏更新的內容,並執行這些操作;也就是說salve執行和master一樣的操作而達到數據同步的目的;

 

   一主一從


關於另幾種架構的探討:

一主多從
   -- salve
  master  -- salve  
   -- salve

--適合於以讀爲主的業務,使用多個salve分擔讀的壓力,但要注意的是這種架構,savle越多,那麼master複製的壓力就越大

 

--------------------------------------------
多主一從     --這種架構不支持

--------------------------------------------


雙主架構        master   -- master

master端如果要進行特別的維護,要停庫;爲了減少寫等待的時間可能會要求把slave轉爲master庫來進行寫

等主庫開服務後,slave庫寫的操作不能複製到master庫,數據不一致,那這種情況,就必須重做複製架構

所以使用master-master架構,互相複製


他們不會循環複製,因爲做複製時會指定ID值,並且不一致

  但是master-master架構,如果兩臺都同讀同寫的話,也會造成數據不一致


  時間點  master A master B
    1  a=1改爲a=2
    2    a=1改爲a=3
    3    a的改變複製過來,並解析,a會又改爲2
    4  b的改變複製過來並解析,a又會改爲3 
 
  問題產生,數據不一致

可能通過一些特殊的參數,指定一些表的寫操作全在一端,另一些表的寫操作全在另一端,也就是說兩邊不會同時寫相同的表,就可以避免上面的問題了


另一種情況避免就是說一般也只把一臺進行寫操作,另一臺只有在寫操作的那臺停服務時才進行寫

 

-------------------------------------------------

      -- salve
級聯架構  master -- salve -- salve
      -- salve


 
 爲了解決一主多從的master的複製壓力
 可以把slave做爲下一級從機的master

 增加複製的級聯層次,造成的延遲更長

 所以這種架構並不是很推薦,一般會進行分拆集羣


-----------------------------------------
     master
     |      | 
環型架構   master  -- master  

--不可行


----------------------------------------------

雙主和級聯合起來


   master
      |
     |      -- slave
   master ---salve -- slave
         -- slave


=========================================================


-------------------------------------------------------------

搭建環境  兩臺虛擬機

  master -- slave
         2.2.2.36    2.2.2.37  

 

這裏選擇使用5.5.13版源碼版

1,先兩邊編譯安裝mysql  


/share/soft/lamp/mysql_source/cmake-2.8.4.tar.gz
/share/soft/lamp/mysql_source/mysql-5.5.13.tar.gz


解壓後

# cd /usr/src/cmake-2.8.4/
# ./configure ; make ;make install

# cd /usr/src/mysql-5.5.13/
# cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DDEFAULT_CHARSET=gbk -DDEFAULT_COLLATION=gbk_chinese_ci -DWITH_EXTRA_CHARSETS=utf8,gb2312 -DENABLED_LOCAL_INFILE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_PARTITION_STORAGE_ENGINE=1

# make ;make install

手動編寫my.cnf配置文件
[root@li /]# mkdir /usr/local/mysql/etc
[root@li /]# vim /usr/local/mysql/etc/my.cnf

[mysqld]
port=3306
basedir=/usr/local/mysql
datadir=/data
pid-file=/var/run/mysqld/mysql55.pid
socket=/var/run/mysqld/mysql55.socket
log-error=/var/log/mysqld/mysql55-err.log
user=mysql

[client]
socket=/var/run/mysqld/mysql55.socket


創建相關目錄,並修改權限
[root@li /]# groupadd -g 27 mysql
[root@li /]# useradd -u 27 -g mysql mysql

[root@li /]# mkdir /data /var/run/mysqld /var/log/mysqld
[root@li /]# chown mysql.mysql /data /var/run/mysqld /var/log/mysqld /usr/local/mysql/   -R

初始化數據庫
# /usr/local/mysql/scripts/mysql_install_db --defaults-file=/usr/local/mysql/etc/my.cnf --basedir=/usr/local/mysql  --user=mysql


拷貝服務腳本
[root@li ~]# cp /usr/src/mysql-5.5.13/support-files/mysql.server /etc/init.d/mysql55

[root@li ~]# chmod 755 /etc/init.d/mysql55

[root@li ~]# vim /etc/init.d/mysql55
 conf=/usr/local/mysql/etc/my.cnf  --修改這一句


啓動服務
[root@li ~]# /etc/init.d/mysql55 start --直接腳本啓動

 

====================================

AB複製前準備
把兩臺mysql啓起來(要求兩臺數據一致),/etc/hosts裏都加上主機名和IP對應,時間同步好,防火牆檢查一下

 


mysql AB複製開始搭建
1,主從數據必須要同步
2,主:要啓用二進制日誌   /usr/local/mysql/etc/my.cnf       log-bin=xxxxx
3,主和從都要設置 server-id值,並且兩邊要不一樣
4,需要建立一個用來複制的用戶,並授於相應權限


   master -- slave
         2.2.2.36    2.2.2.37  

 

 

第一步;改配置文件

master的
[mysqld]
log-bin=mysql-bin
server-id=2

slave的
 [mysqld]
 server-id=3

/etc/init.d/mysql5  重啓服務

 


第二步:授權


master上授權,super和replication slave都是複製要用的權限
mysql> grant super,replication slave on *.* to 'li'@'2.2.2.37' identified by '123';
mysql> flush privileges;


slave上最好使用剛纔授權的用戶是遠程登錄一下主
[root@slave src]# /usr/local/mysql/bin/mysql -u li -h 2.2.2.36 -p123
ERROR 1130 (HY000): Host '::ffff:2.2.2.36' is not allowed to connect to this MySQL server
--上面是IPV6所造成的影響,所以要去主上面重新授權


master上重新授權,寫上IPv6的形式,或者使用%符號代替所以(但不建設這樣做,這樣就沒有對slave做權限控制)
mysql> grant super,replication slave on *.* to 'li'@'::ffff:2.2.2.36' identified by '123';
mysql> flush privileges;

再驗證一下,發現登陸OK


第三步:查看master的正在寫的二進制文件名和位置
mysql> flush tables with read lock;  --先加鎖,防止兩邊數據不一致
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      681 |              |                  |
+------------------+----------+--------------+------------------+

二進制文件名  正在寫入的位置


slave端量的配置
mysql> slave stop;
Query OK, 0 rows affected, 1 warning (0.00 sec)


mysql> change master to
    -> master_user='li',
    -> master_password='123',
    -> master_host='2.2.2.36',  --主的IP
    -> master_port=3306,   --端口,如果爲3307就要換成3307
    -> master_log_file='mysql-bin.000001', --主上面查到的文件名
    -> master_log_pos=681;   --主上面查到的位置號

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)


mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 2.2.2.36
                  Master_User: li
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 681
               Relay_Log_File: mysql55-relay-bin.000002
                Relay_Log_Pos: 253
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes   --這裏兩個YES,表示兩個線程OK
              Replicate_Do_DB:
          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: 681
              Relay_Log_Space: 411
              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:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
1 row in set (0.00 sec)

...................................

回到master端解鎖:
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)


進行測試:

1,先比較主,從的數據目錄文件的不同

[root@master ~]# ls /data/ --主的
ibdata1      mysql             performance_schema
ib_logfile0  mysql-bin.000001  test
ib_logfile1  mysql-bin.index


[root@slave ~]# ls /data/ --從的
ibdata1                   mysql55-relay-bin.000002
ib_logfile0               mysql55-relay-bin.index
ib_logfile1               performance_schema
master.info               relay-log.info
mysql                     test
mysql55-relay-bin.000001

 

驗證2:只有master寫,slave可以看到
 slave寫,master看不到

如果複製有問題,刪除slave端/data/master.info再做


驗證3:把從重啓後,再上去查看狀態,還是連接的,沒什麼影響

 把主重啓後,再去slave上去查看狀態,發現重試時間爲60秒,等60秒後又自動連接OK了

 

=================================


------------------------------------------------------------

一主多從的做法


 就是上面的步驟有幾個從就做幾次

 

------------------------------------------------------------------------


雙主架構的做法:

 在上面的slave機也打開二進制日誌,反着做一遍就行,注意做的過程中,保證數據一致

 

--------------------------------------------------------------


級聯架構      

  master -slave -slave

 

把中間的從也要打開二進制日誌。但是它默認不把應用master的操作記錄到自己的二進制日誌。所以需要打開一個參數讓它記錄,纔可以傳給第三級的從


# /usr/local/mysql/bin/mysqld --verbo --help |grep log-slave

  --log-slave-updates Tells the slave to log the updates from the slave thread
                      --log-slave-updates is used.
log-slave-updates                                 FALSE

--默認值爲false,所以需要在配置文件里加上log-slave-updates=1,然後重啓服務

所以打開中間從的配置文件
# vim /usr/local/mysql/etc/my.cnf  --加上下面兩句,然後重啓服務
log-bin=mid-slave
log-slave-updates=1 

 

然後在中間從和第三級的從之間再做一次AB複製就可以了

 

我的結構圖


  master     slave         slave

2.2.2.36     2.2.2.37        2.2.2.35  

sever-id=2    server-id=3        server-id=4
log-bin=master    log-bin=mid-slave 
     log-slave-updates=1


===============================

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章