2007年8月22日 星期三

同一台電腦啟動兩個以上MySQL

同一台啟動兩個MySQL,要注意的就是不能listen同一個port 和 資料庫資料
因此要另外設定一個 my.cnf ,裡面要寫另外一個資料庫要 lsiten 在哪個ip:port,以及他所使用的sock和datadir在哪,舉例如下:

[mysqld_safe]
err-log = /var/log/mysql/mysql-20.err

# add a section [mysqld-4.1] or [mysqld-5.0] for specific configurations
[mysqld]
port = 3307
socket = /var/run/mysqld/mysqld-20.sock
pid-file = /var/run/mysqld/mysqld-20.pid
log-error = /var/log/mysql/mysqld-20.err
datadir = /mnt/20/mysql
skip-locking

# security:
# using "localhost" in connects uses sockets by default
# skip-networking
bind-address = 192.168.1.7

然後以
# mysqld --defaults-file=/etc/mysql/my-20.cnf 啟動

2007年8月18日 星期六

mysql 4.1/5.0 升級亂碼問題

緣由

升級mysql到4.1/5.0等支援unicode的版本後,馬上會遇到資料庫變亂碼的問題,主要的原因是早期的資料庫是採用 latin1 編碼去儲存 utf8, big5 等,到了 4.1 以後的版本開始支援unicode多國語系,所以從早期的升級上來會變成亂碼。


解決方法

先把有問題的資料庫用以下指令匯出
mysqldump -h 192.168.1.7 --default-character-set=latin1 tcse07 -p --compatible=mysql40 > tcse07.sql
以上指令的意思是要以 latin1 編碼的方式匯出資料庫 tcse07 的內容到 tcse07.sql 檔案,後面的 --compatible=mysql40 是為了使匯出的資料不包含 DEFAULT_CHARSET = latin1 的語系設定,這樣才可以確保匯出的資料是真正原始的資料,而非把 latin1 以 utf8 讀出來的資料

接下來要把轉過的資料在匯入資料庫中
這邊建議匯出以後,先把本來的資料庫 tcse07 刪除,重新建立使其使用 utf8 編碼,之後用以下指令把資料放回去
mysql -p --default-character-set=big5 tcse07
以上指令是要把目前要匯入資料庫 tcse07 的資料,以 big5 的方式讀取 tcse07.sql 並存入 tcse07 資料庫中

或是也可以在php連線的時候,指定以 latin1 的方式去讀去資料表的資料
mysql_connect("192.168.1.7", "root", "xxxx");
mysql_query("SET NAMES latin1");

總結

以上方法的大概就是要讓mysql在讀取以前舊的資料庫的時候,能夠以當時存進去的編碼方式讀出來
在 mysql 支援 Unicode 以前,其存資料的編碼都是 latin1,不管你實際上是用 big5 或 utf8,真正存到內部以後都是當作 latin1 處理
但是後期支援 Unicode 的版本,對於以前的資料會當作是 utf8 去把他讀出來,也就是會背景自動作 latin1 -> utf8 的動作,而不是 big5 -> utf8 的轉換,這也是導致亂碼的原因


其他

big5是以 2 bytes 的方式存檔,而 utf8 是 3 bytes,因此如果看到亂碼的時候,一個中文有2個亂碼,就是 big5,有三個就是 utf8
另外還有當以前php網頁存資料庫是big5的時候,如果不想把網頁改utf8,可以用以下方式解決資料庫讀出亂碼問題
mysql_connect("192.168.1.7", "root", "xxxx");
mysql_query("SET NAMES big5");
ps. SET NAMES的意思是要把資料庫中的資料轉成什麼編碼讀出來,例如存utf8,讀出成big5,但是必須在原本資料庫就是正確的情況下才有用

code:
/* 以Latin1讀取資料庫, 並於畫面顯示INSERT語法
* 使用時須加參數dump.php?table=aaaa
*/
$table=$_GET['table'];
mysql_connect("localhost", "user", "pass") or die(mysql_error());
mysql_select_db("loopek")or die(mysql_error());
mysql_query("SET NAMES 'latin1'");

$r=mysql_query("SELECT * FROM `$table`") or die(mysql_error());

while( $d=mysql_fetch_assoc($r) ) {
$a="INSERT INTO `$table` VALUES (";
foreach($d as $data)
$a = $a."'$data', ";
$a=substr($a, 0, strlen($a)-2);
echo "$a);<br>";
}

由php建立shadow密碼

如果把/etc/shadow搬到mysql裡面當作使用者認證
這時passwd將無法改變資料庫的密碼
可以改用php的方式去改變

在php中有crypt可用

On systems where the crypt() function supports multiple encryption types, the following constants are set to 0 or 1 depending on whether the given type is available:

  • CRYPT_STD_DES - Standard DES-based encryption with a two character salt

  • CRYPT_EXT_DES - Extended DES-based encryption with a nine character salt

  • CRYPT_MD5 - MD5 encryption with a twelve character salt starting with $1$

  • CRYPT_BLOWFISH - Blowfish encryption with a sixteen character salt starting with $2$ or $2a$


但是在不同系統似乎會有不同結果
例如在13.13可以直接產生正確的 CRYPT_MD5 密碼
但是在26.7卻會產生 CRYPT_BLOWFISH 密碼

$salt_str='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.';
$salt=substr(str_shuffle($salt_str), 0, 8);

因此必須手動處理crypt的干擾碼:str_shuffle會隨機從字串中選出
substr才可以選其中八碼來用
最後crypt('aaa', '$1$'.$salt) 便可以產生正確的 CRYPT_MD5密碼給shadow使用
Related Posts Plugin for WordPress, Blogger...