top
Loading...
6.9.復制FAQ
6.9. 復制FAQ

Q:如果主服務器正在運行并且不想停止主服務器,怎樣配置一個從服務器?

A:有多種方法。如果你在某時間點做過主服務器備份并且記錄了相應快照的二進制日志名和偏移量(通過SHOW MASTER STATUS命令的輸出),采用下面的步驟:

1.    確保從服務器分配了一個唯一的服務器ID號。

2.    在從服務器上執行下面的語句,為每個選項填入適當的值:

            mysql> CHANGE MASTER TO

                ->     MASTER_HOST='master_host_name',
                ->     MASTER_USER='master_user_name',
                ->     MASTER_PASSWORD='master_pass',
                ->     MASTER_LOG_FILE='recorded_log_file_name',
              ->     MASTER_LOG_POS=recorded_log_position;

3.    在從服務器上執行START SLAVE語句。

如果你沒有備份主服務器,這里是一個創建備份的快速程序。所有步驟都應該在主服務器主機上執行。

1.    發出該語句:

     mysql> FLUSH TABLES WITH READ LOCK

2.    仍然加鎖時,執行該命令(或它的變體):

     shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql

3.    發出該語句并且確保記錄了以后用到的輸出:

     mysql>SHOW MASTER STATUS

4.    釋放鎖:

     mysql> UNLOCK TABLES

一個可選擇的方法是,轉儲主服務器的SQL來代替前面步驟中的二進制復制。要這樣做,你可以在主服務器上使用mysqldump --master-data以后裝載SQL轉儲到到你的從服務器。然而,這比進行二進制復制速度慢。

不管你使用這兩種方法中的那一個,當你有一個快照和記錄了日志名與偏移量時,后來根據說明操作。你可以使用相同的快照建立多個從服務器。一旦你擁有主服務器的一個快照,可以等待創建一個從服務器,只要主服務器的二進制日志完整。兩個能夠等待的時間實際的限制是指在主服務器上保存二進制日志的可用硬盤空間和從服務器同步所用的時間。

你也可以使用LOAD DATA FROM MASTER。這是一個方便的語句,它傳輸一個快照到從服務器并且立即調整日志名和偏移量。將來,LOAD DATA FROM MASTER將成為創建從服務器的推薦方法。然而需要注意,它只工作在MyISAM 表上并且可能長時間持有讀鎖定。它并不象我們希望的那樣高效率地執行。如果你有大表,執行FLUSH TABLES WITH READ LOCK語句后,這時首選方法仍然是在主服務器上制作二進制快照。

Q:從服務器需要始終連接到主服務器嗎?

A:不,不需要。從服務器可以宕機或斷開連接幾個小時甚至幾天,重新連接后獲得更新信息。例如,你可以在通過撥號的鏈接上設置主服務器/從服務器關系,其中只是偶爾短時間內進行連接。這意味著,在任何給定時間,從服務器不能保證與主服務器同步除非你執行某些特殊的方法。將來,我們將使用選項來阻塞主服務器直到有一個從服務器同步。

Q:我怎樣知道從服務器與主服務器的最新比較? 換句話說,我怎樣知道從服務器復制的最后一個查詢的日期?

A:你可以查看SHOW SLAVE STATUS語句的Seconds_Behind_Master列的結果。參見6.3節,“復制實施細節”。

當從服務器SQL線程執行從主服務器讀取的事件時,它根據事件時間戳修改自己的時間(這是TIMESTAMP能夠很好復制的原因)。在SHOW PROCESSLIST語句輸出的Time列內,為從服務器SQL線程顯示的秒數是最后一個復制事件的時間戳和從服務器主機的實際時間之間相差的秒數。你可以使用它來確定最后一個復制事件的日期。注意,如果你的從服務器與主服務器連接斷開一個小時,然后重新連接,在SHOW PROCESSLIST結果中,你可以立即看到從服務器SQL線程的Time值為3600。這可能是因為從服務器執行的語句是一個一小時之前的。

Q:我怎樣強制主服務器阻塞更新直到從服務器同步?

A:使用下面的步驟:

1.    在主服務器上,執行這些語句:

     mysql> FLUSH TABLES WITH READ LOCK;

     mysql> SHOW MASTER STATUS;

 

記錄SHOW語句的輸出的日志名和偏移量。這些是復制坐標。

2.    在從服務器上,發出下面的語句,其中Master_POS_WAIT()函數的參量是前面步驟中的得到的復制坐標值:

     mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);

SELECT語句阻塞直到從服務器達到指定的日志文件和偏移量。此時,從服務器與主服務器同步,語句返回。

3.    在主服務器上,發出下面的語句允許主服務器重新開始處理更新:

     mysql> UNLOCK TABLES

Q:當設置雙向復制時我應該知道發出那些語句?

AMySQL復制目前不支持主服務器和從服務器之間的任何鎖定協議來保證分布式(跨服務器)更新的原子性。換句話說,這樣做是可能的:客戶A根據協作-主服務器1更新,同時,在它傳給協作-主服務器2之前,客戶B能夠根據協作-主服務器2更新,這樣客戶A的更新與它在協作-主服務器1的更新不同。這樣,當客戶A根據協作-主服務器2更新時,它產生的表與在協作-主服務器1上的不同,即使所有根據協作-主服務器2的更新已經傳過來。這意味著,在雙向復制關系中,你不應該把兩個服務器串連在一起,除非你確信任何順序的更新是安全的,或者除非你在客戶端代碼中注意怎樣避免更新順序錯誤。

你還必須認識到從更新角度,雙向復制實際上并不能顯著地提高性能(或者根本不能提高性能)。兩個服務器都需要做相同數量的更新,如同在一個服務器做的那樣。唯一的差別是鎖競爭要少,這因為源于另一個服務器的更新在一個從線程中序列化。即使這個益處可能被網絡延遲抵消。

Q:怎樣通過復制來提高系統的性能?

A:你應將一個服務器設置為主服務器并且將所有寫指向該服務器。然后根據預算配置盡可能多的從服務器以及棧空間,并且在主服務器和從服務器之間分發讀取操作。你也可以用--skip-innodb--skip-bdb--low-priority-updates以及--delay-key-write=ALL選項啟動從服務器,以便在從服務器端提高速度。在這種情況下,為了提高速度,從服務器使用非事務MyISAM表來代替InnoDBBDB表。

Q:為了使用高性能的復制,我應該在自己的應用程序中怎樣準備客戶端代碼?

A:如果你的代碼中數據庫訪問部分已經正確地模塊化,應該能夠平滑和容易地轉換為在復制步驟中運行的代碼。僅需要更改數據庫訪問執行部分,以便發送所有的寫操作到主服務器,以及發送讀操作到主服務器或某個從服務器。如果你的代碼沒有這個級別,設置一個復制系統以便清除。應先通過下面的函數創建一個包裝庫或模塊:

·         safe_writer_connect()

·         safe_reader_connect()

·         safe_reader_statement()

·         safe_writer_statement()

每個函數名的safe_意味著函數比較小心地處理所有錯誤。你可以使用不同名的函數。重要是對于讀連接、寫連接、讀和寫有一個統一的接口。

然后,你應該轉換客戶端代碼使用包裝庫。剛開始這可能是痛苦和恐慌的過程,但從長遠來看是值得的。使用剛才討論的方法的所有應用程序都能夠利用主服務器/從服務器配置的優越性,即使是含有多個從服務器的配置。代碼非常容易維護,并且添加排錯選項也很容易。你僅需要修改一兩個函數;例如,記錄每個語句執行的時間,或者你的上千個語句中哪個語句發生了錯誤。

如果你已經編寫了許多代碼,你可能想使用replace工具自動進行轉換,該工具隨標準MySQL一起發布,或可以自己編寫轉換腳本。理想情況,你的代碼使用一致的程序轉換風格。否則,可能最好重新編寫代碼,或者至少手工對其進行規則化以使用一致的風格。

QMySQL復制能夠何時和多大程度提高系統性能?

AMySQL復制對于頻繁讀和頻繁寫的系統具有最大好處。理論上,通過使用單個主服務器/多從服務器設置,可以通過添加更多的從服務器來擴充系統,直到用完網絡帶寬,或者你的更新負載已經增長到主服務器不能處理的點。

在獲得的收益開始吃平之前,為了確定可以有多少從服務器,以及可以將你的站點的性能提高多少,需要知道查詢模式,并且要通過基準測試并根據經驗確定一個典型的主服務器和從服務器中的讀取(每秒鐘讀取量,或者max_reads)吞吐量和寫(max_writes)吞吐量的關系。通過一個假設的帶有復制的系統,本例給出了一個非常簡單的計算結果。

假設系統負載包括10%的寫和90%的讀取,并且我們通過基準測試確定max_reads1200 2 × max_writes。換句話說,如果沒有寫操作,系統每秒可以進行1,200次讀取操作,平均寫操作是平均讀操作所用時間的兩倍,并且關系是線性的。我們假定主服務器和每個從服務器具有相同的性能,并且我們有一個主服務器和N個從服務器。那么,對于每個服務器(主服務器或從服務器),我們有:

reads = 1200 2 × writes

reads = 9 × writes / (N + 1) (讀取是分離的, 但是寫入所有服務器)

9 × writes / (N + 1) + 2 × writes = 1200

writes = 1200 / (2 + 9/(N+1))

最后的等式表明了N個從服務器的最大寫操作數,假設最大可能的讀取速率是每分鐘1,200次,讀操作與寫操作的比率是9

如上分析可以得到下面的結論:

·         如果N = 0(這表明沒有復制),系統每秒可以處理大約1200/11 = 109個寫操作。

·         如果N = 1,每秒得到184個寫操作。

·         如果N = 8,每秒得到400個寫操作。

·         如果N = 17,每秒得到480個寫操作。

·         最后,當 N 趨于無窮大(以及我們預算的負無窮大)時,可以得到非常接近每秒600個寫操作,系統吞吐量增加將近5.5倍。然而,如果只用8個服務器,增加接近4倍。

請注意,這些計算假設網絡帶寬無窮大并忽略掉了其它一些因素,那些因素可能對系統產生重要的影響。在許多情況下,不能執行與剛才類似的計算,即如果添加N臺復制從服務器,應該準確預報系統將發生哪些影響。回答下面的問題應能夠幫助你確定復制是否和在多大程度上能夠提高系統的性能:

·         系統上的讀取/寫比例是什么?

·         如果減少讀取操作,一個服務器可以多處理多少寫負載?

·         網絡帶寬可滿足多少從服務器的需求?

Q:如何使用復制來提供冗余/高可用性?

A:利用目前的可用特性,必須設置一個主服務器和一個從服務器(或多個從服務器),以及寫一個腳本來監視主服務器是否啟動。如果主服務器失敗,通知應用程序和從服務器切換主服務器。下面是一些建議:

·         告知從服務器更改其主服務器,使用CHANGE MASTER TO語句。

·         通知應用程序主服務器位置的一個很好的方法是對主服務器提供動態DNS入口。用bind可以使用nsupdate動態更新DNS

·         應該用--logs-bin選項而不用 --logs-slave-updates選項運行從服務器。這樣,一旦你在其它從服務器上發出STOP SLAVE; RESET MASTER, 以及CHANGE MASTER TO語句該從服務器可以切換為主服務器。例如,假設有下面的設置:

·                       WC
·                        
·                         v
·                 WC----> M
·                       / | 
·                      /  |  
·                     v   v   v
·                    S1   S2  S3

M代表主服務器,S代表從服務器,WC代表發出數據庫寫和讀取操作的客戶;只發出數據庫讀取操作的客戶沒有給出,因為它們不需要切換。S1S2以及S3是從服務器,用--logs-bin選項而沒有用--logs-slave-updates運行。因為從服務器收到的主服務器的更新沒有記錄在二進制日志中,除非指定 --logs-slave-updates選項,每個從服務器上的二進制日志是空的。如果因為某些原因M 變得不可用,你可以選取一個從服務器變為新的主服務器。例如,如果你選取了S1,所有WC應該重新指向S1S2,并且S3然后應從S1復制

確保所有從服務器已經處理了中繼日志中的所有語句。在每個從服務器上,發出STOP SLAVE IO_THREAD語句,然后檢查SHOW PROCESSLIST語句的輸出,直到你看到Has read all relay log。當所有從服務器都執行完這些,它們可以被重新配置為一個新的設置。在被提升為主服務器的從服務器S1上,發出STOP SLAVERESET MASTER語句。

在其它從服務器S2S3,使用STOP SLAVECHANGE MASTER TO MASTER_HOST='S1'(其中'S1'表示S1實際的主機名)。為CHANGE MASTER添加關于從S2S3如何連接到S1所有信息(userpasswordport)。在CHANGE MASTER命令中,不需要指定從其讀取的S1的二進制日志名或二進制日志位置:我們知道它是第1個二進制日志,位置是4,這是CHANGE MASTER命令的默認值。最后,在S2S3使用START SLAVE 命令。

然后,指示所有WC 把它們的語句指向S1此后,WC發出的所有發送到S1更新語句被寫入S1二進制日志,S1則包含M死掉之后的發送到 S1的每一個更新語句。

結果是下面的配置:

       WC
      /
      |
 WC   |  M(unavailable)
     |
     |
    v v
     S1<--S2  S3
      ^       |
      +-------+

M重新啟動后,你必須在M發出相同的CHANGE MASTER語句,與在S2S3上發出的語句一樣,以便M變為S1從服務器并且恢復在它宕機后丟失的所有WC寫操作。要把 M 再次作為主服務器(例如,因為它是功能最強的機器),使用前面的步驟,好像S1不可用并且M變為一個新的主服務器一樣。在這個過程中,在S1S2以及S3作為M從服務器之前,不要忘記在M運行RESET MASTER。否則,它們可能拾取M變得不可用之前的舊WC寫操作。

我們目前正在MySQL集成自動主服務器選擇系統,但在準備好之前,你必須創建自己的監控工具。

作者:mysql.com
來源:http://dev.mysql.com/doc/refman/5.1/zh/replication.html
北斗有巢氏 有巢氏北斗