2010/12/7

Oracle TNS-12547 的問題

今早公司的oracle 發生了逼個奇怪的狀況
就是 DB 還好好的
但是 tns 竟然自己下載去了

我手動去執行lsnrctl 想要啟動它
沒想到它立刻吐出 TNS-12547 的錯誤回來給我

真的是怪事

經過在goole 上查訪一下

終於了解, 原來是 listener.log 太大了, 超過了 2G 便在動卸下來

因此到 $ORACLE_HOME/network/log 下

mv listener.log listener.log.20101205

然後回到 $ORACLE_HOME/bin 下去執行 lsnrctl

嘿, 果然又恢復了....

又學到一樣了.....

2010/1/15

[php] 將 csv 檔轉入 mysql 去

再來便是要讓使用者自行可以將打在 csv 檔內的資料轉入到 mysql table 去

這便麻煩許多了

因為中文編碼方式到底是 big5 還是 utf-8 ? 恐怕 user 自己也不知道吧 !

此外, 第一行有沒有標題列 ? 這也得考慮到

當然了格式到底對不對呢 ? 這也是一大問題

基於以上的不確定性, 所以我便開放攔位讓 user 自行決定

且當一轉入時, 我並不急著就存到 table 去, 先把前十筆資料再次的顯示在營幕上

讓 user 自己判斷要不要轉進去, 沒問題時在確定就好

若 user 要亂轉進去的話, 各人造的業各人自己去擔吧,

因為到時真正要的資料埋在一堆垃圾,而致找不到自己要的資料時, 別人也是愛莫能助呀.,....

不多廢話了, 以下便是我的步驟

1. 這裏提供 user 自行來決定是否有標題列 ? 以及中文的格式是那一種 !!!!
當然了還提供了檔案上傳的欄位, 也 作了必需要真的上傳檔案的檢查...




2. 當 user 按下 上傳以後, 執行權限便轉移到 quest_import_exe.php 去




說明如下:
* $first_rec
==> 小弟用此變數來判定是不是第一列,
當 csv 檔有標題列時, 用這變數來將標題列惕除不要轉入

* if ( $_FILES['CSVfile']['size'] ) {
==> 當轉入的 csv 檔, 不能是空檔, size 要有時, 才可以開始轉檔

* $sql = "select max(uid) uid from quest_file where cno = '".$cno."'";
$res2 = @$mdb2->query($sql);
$row2 = $res2->fetchAll();
$uid = intval($row2[0]['uid']) + 1;
==> 這一段是將原有序號抓出來加 1 , 做為此次轉入來賓的起始序號

* if ( $china == "BIG5" ){
setlocale(LC_ALL, 'zh_TW.BIG5');
}else{
setlocale(LC_ALL, 'en_US.UTF-8');
}
==> 針對 user 選擇 big5 or utf-8 來作 csv 檔的編碼方式設定

* 接下來一大段, 直接用文字來介紹了
( 先說明, 這段的寫法有點笨, 應該有更好的寫法才是 )

小弟特別在此將前 10 筆的 data 顯示出來, 讓 user 在行確認一遍
當畫面上的標題列或是中文沒問題時,再點選"轉換正確"
正式開始轉檔

3 開始轉檔

(php) 將 mysql 的資料轉成 csv 檔

最近因需求, 必需提供使用者將自己的來賓資料轉成 excel 檔

所以開始 study 怎樣將資料轉成會員所需的 csv 檔

以下便是我的程式

1. 標題列的產生

$exportString = 'Customer No'.",".'Serial No'.",".'Guest Name';
$exportString .= ",".'Sex'.",".'Age'.",".'Telephone'.",".'Mobile'.",";
$exportString .= "Address".","."Remark".","."Create Date".","."Last Modify Date";
$exportString .= "\r\n";

2. 到 table 去將資料找出來

$sql = "select * from guest_file where cno = '".$cno."' order by uid desc";

3. 將找出來的資料一一組合到 string 裏面去

$res2 = @$mdb2->query($sql);
$row2 = $res2->fetchAll();
$num2 = $res2->numRows();
for( $i=0; $i<$num2; $i++)
{
$exportString .= $cno.",".$row2[$i]['uid'].",".$row2[$i]['uname'].",";
$exportString .= $row2[$i]['usex'].",".$row2[$i]['uage'].",".$row2[$i]['utel'].",".$row2[$i]['umobile'].",";
$exportString .= $row2[$i]['uaddress'].",".$row2[$i]['remark'].",".$row2[$i]['create_date'].",".$row2[$i]['tx_date'];
$exportString .= "\r\n";
}

4. 將存在 string 內的變數丟成 csv 檔

header('Content-Type: text/html; charset=utf-8');
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: attachment; filename=Mydata-" . date("Y-m-d").".csv");
print $exportString;

==> 其中預設的 csv 檔先給一個檔名 Mydata-YYYYMMDD.csv 的日期檔名...

2010/1/7

備份 oracle 的資料到另一台機器的簡單作法

我的公司是個很窮的公司

一切的資訊運作都是以最省錢的方式來進行

所以連備份最重要的網站平台資料也得用最省的方式來進行了

因為 web server 上面全是程式, 所以要背份的話還容易, 因為程式倒是很少會去動到

因此只要一有異動到程式時在整個 tar 下來, 就萬事 ok 了

但 database 的資料可沒這麼簡單了

不但每天要自動的讓系統去備份, 還得考慮到將資料存到別的地方去

免得當機器掛掉時, 連裏面的資料都拿不出來

另一方面也得要有可以立刻倒資料進去的 備用 oracle 主機才行

因為我的另一台 ap server 上工作比較輕鬆點,平日除了 ap server 的工作要處理外, 就沒什麼大事要幹

所以我便在其上灌了一套 oracle , 並把整個網站平台所需要用到的 table , sp, trigger ....通通架好, 然後再把 oracle 關掉, 等待備用

所以現在最重要的便是要將 oracle 資料 dump 出來後, 轉存到另一台機器

基於雞蛋不要全放在同一籠的到理

所以我便用 mail server 來當 oracle 資料的備份機

整個作業如下

1. db server 自動備份資料

db server 的 oracle 帳號 下, 建立一個 backup.sh 檔
內容如下 :

export ORACLE_HOME=/oracle/product/9.2.0
export PATH=$PATH:$ORACLE_HOME/bin:$HOME/bin
export NLS_LANG=AMERICAN_AMERICA.UTF8

exp userid=userid/passwd@KILLER.LOCALDOMAIN file=/backup/daily/userid-data.dmp owner=userid log=/backup/daily/userid-data.log

==> 將所有的資料備份到 /backup/daily/userid-data.dmp 去
我並沒有讓檔名中有日期時間, 因為那將會使硬碟很快就爆了, 如此可以讓檔案一直覆蓋, 反正資料等下也會被備走

2. 設定 crontab

crontab -e
內容如下 :

10 12,23 * * * sh /home/oracle/backup.sh >> /home/oracle/log/backup.log 2>> /home/oracle/log/backup.err

每天的中午和晚上各備份一次,


3. 接下來到 mail server 上去, 首先要建立兩台 server 間的信任關係
在要執行備份的帳互去, 假設是 backup 這個帳號
執行 ssh-keygen -t dsa ==> 用來產生一組 Private/Public Key
  內定會在 .ssh/ 目錄下產生兩個檔案: id_dsa 及 id_dsa.pub (不要設定 passphrase)
 
4. 接下來將 id_da.pub 傳送到 db server 上去

5. 將 id_da.pub 存到 oracle db server 的 /home/oracle/.ssh 上面去
並 改名 mv id_dsa.pub authorized_keys

此時, mail server 已經獲得 oracle db server 的信任了, 以經可以用 ssh 到上面去了

6. 回到 mail server 上面, 進到 backup 帳號去
寫一個 backup_data.sh

內容如下 :

scp oracle@192.168.1.133:/backup/daily/userid-data.dmp /backup/daily

==> 到我的 oracle server ( 假設 ip 是 192.168.1.133 ) , 利用 scp (透過 ssh 抓資料用的 ) 到 /backup/daily 下將之前 dump 下來的oracle 資料 userid-data.dmp 抓過來, 存放到 mail server 上的 /backup/daily 下方去

然後進 crontab 去設定每天自動抓去

crontab -e

40 12,23 * * * sh /home/young/backup_data.sh

因為 前面 oracle data 的dump 是從 10 分開始的, 給機器 30 分的 dump 時間, 所以從 40 分開始 跑

7. 不過, 我自己手動跑一下來試看看

a. 到 oracle server 以 oracle 帳號進入後
執行 ./backup.sh
跑了將近十分鐘後, 資料才dump 下來

b. 到 mail server 上以 backup 登入
執行 ./backup_data.sh
一樣的已將資料傳了過來
畫面如下 :
userid-data.dmp 100% 2,145MB 11.2MB/s 2:13

大功告成.............