install mysqlnd-ms for master/slave split

site : http://www.php.net/manual/en/book.mysqlnd-ms.php
source iste : http://pecl.php.net/package/mysqlnd_ms

case : amazon linux ami

amazon linux ami 2012.09-release-notes 에서는 httpd24(apache 2.4)를 사용해야 한다고 한다.

yum install httpd24 php54-mcrypt php54-pecl-memcache php54-gd php54-devel php54-cli php54-mysqlnd

# simple install
# sudo pecl install mysqlnd_ms

wget http://pecl.php.net/get/mysqlnd_ms-1.4.2.tgz
tar xvfz mysqlnd_ms-1.4.2.tgz
cd mysqlnd_ms-1.4.2
phpize
./configure
make
sudo make install

sudo vi /etc/php.d/mysqlnd_ms.ini

extension=mysqlnd_ms.so
mysqlnd_ms.enable=1
mysqlnd_ms.config_file=/var/www/mysqlnd_ms_plugin.conf

vi /var/www/mysqlnd_ms_plugin.ini

{
    "localhost": {
        "master": {
            "master_0": {
                "host": "192.168.x.x",
                "port": "3306"
            }
        },
        "slave": {
            "slave_0": {
                "host": "localhost",
                "socket": "\/var\/lib\/mysql\/mysql.sock"
            }
        }
    }
}

제대로 master/slave spilt가 되는지 확인하기 위해선 다음 소스를 이용한다. 결과로 @myrole = ” 이 나오면 master/slave가 나뉘는 것이다.

<?php
$mysqli = new mysqli("localhost", "id", "password", "database");
if (mysqli_connect_errno())
/* Of course, your error handling is nicer... */
die(sprintf("[%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));

/* Connection 1, connection bound SQL user variable, no SELECT thus run on master */
if (!$mysqli->query("SET @myrole='master'")) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}

/* Connection 2, run on slave because SELECT */
if (!($res = $mysqli->query("SELECT @myrole AS _role"))) {
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
} else {
$row = $res->fetch_assoc();
$res->close();
printf("@myrole = '%s'\n", $row['_role']);
}
$mysqli->close();
?>

wordpress 의 경우 mysqlnd_ms 를 사용할 경우 mysql_get_server_info 명령어가 듣지 않는다. 이유는 master/slave spilt가 되고나서 하나의 쿼리라도 던지기 전에 미리 mysql_get_류의 명령어를 던지게 되면 NULL값이라 segmentation fault 가 난다. /wordpress/wp-includes/wp-db.php 파일의 db_version() 함수에서 나오는 값을 고정시키면 오류를 피할수 있다.

PHP segmentation fault when mysqlnd_ms is enabled

/**
* The database version number.
*
* @since 2.7.0
*
* @return false|string false on failure, version number on success
*/
function db_version() {
	// mysqlnd_ms patch 5.5.28
	return '5.5.28';
	// return preg_replace( '/[^0-9.].*/', '', mysql_get_server_info( $this->dbh ) );
}

case : ubuntu 12.04LTS

sudo apt-get install php5-dev
apt-get source php5

vi php-x.x/ext/mysqlnd/mysqlnd_portability.h

# ---- edit line 40 ----
#  include <ext /mysqlnd/php_mysqlnd.h>

sudo cp -R php-x.x/ext/mysqlnd /usr/include/php5/ext
sudo pecl install mysqlnd_ms