1. 程式人生 > >使用Loadrunner11錄製MySQL協議指令碼

使用Loadrunner11錄製MySQL協議指令碼

因為在Loadrunner中沒有MySQL協議,故無法直接採用MySQL協議來錄製測試MySQL的指令碼。目前用的比較多的方法有兩種,一種是使用ODBC的方式來錄製MySQL指令碼,但流程過於複雜,限制較多;一種是直接在Loadrunner中通過C Vuser型別協議,呼叫MySQL的中的libmysql.dll進行MySQL指令碼的編寫。此處,我們選擇後者進行指令碼的編寫。

 

(1)安裝mysql

下載mysql的伺服器/客戶端安裝包並安裝,mysql的版本最好跟被測的mysql資料庫伺服器的版本一致,安裝的時候,按照預設選項一直點下一步就行了。

安裝mysql的目的主要是為了獲libmysql.dll動態庫,因為libmysql.dll不僅是mysql中一個非常重要的動態連結庫,還是我們接下來編寫mysql指令碼必須引用的。如果可以從被測mysql伺服器端獲取該libmysql.dll動態庫,也可以不再安裝mysql。

(2)在Lodrunner中新建C Vuser型別指令碼

此處我們使用的是Loadrunner11。開啟VUGen,新建C Vuser型別指令碼。

C Vuser型別指令碼實際上就是C語言型別的指令碼,是無法進行錄製的,只能自己根據實際業務的需要編寫。

 

(3)附加libmysql.dll動態連結庫

    在VUGen中,選擇File-->Add Files to Script,將libmysql.dll附加到指令碼中。將libmysql.dll附加到指令碼中,就可以直接使用libmysql.dll裡的函數了,而且指令碼還直接可以移植到別的電腦上使用,不再受libmysql.dll所在的位置限制。因為有些人附加libmysql.dll動態庫採用絕對路徑進行的,當libmysql.dll所在的位置變化時,還要相應的調整libmysql.dll所在絕對路徑。

 

 

libmysql.dll動態連結庫提供了很多函式來對資料庫進行操作,大致可以分為以下幾類:

 

第一部分 控制類函式

mysql_init()初始化MySQL物件

mysql_options()設定連線選項

mysql_real_connect()連線到MySQL資料庫

mysql_real_escape_string()將查詢串合法化

mysql_query()發出一個以空字元結束的查詢串

mysql_real_query()發出一個查詢串

mysql_store_result()一次性傳送結果

mysql_use_result()逐行傳送結果

mysql_free_result()釋放結果集

mysql_change_user()改變使用者

mysql_select_db()改變預設資料庫

mysql_debug()送出除錯資訊

mysql_dump_debug_info()轉儲除錯資訊

mysql_ping()測試資料庫是否處於活動狀態

mysql_shutdown()請求資料庫SHUTDOWN

mysql_close()關閉資料庫連線

第二部分 資訊獲取類函式

mysql_character_set_name()獲取預設字符集

mysql_get_client_info()獲取客戶端資訊

mysql_host_info()獲取主機資訊

mysql_get_proto_info()獲取協議資訊

mysql_get_server_info()獲取伺服器資訊

mysql_info()獲取部分查詢語句的附加資訊

mysql_stat()獲取資料庫狀態

mysql_list_dbs()獲取資料庫列表

mysql_list_tables()獲取資料表列表

mysql_list_fields()獲取欄位列表

第三部分 行列類操作函式

mysql_field_count()獲取欄位數

mysql_affected_rows()獲取受影響的行數

mysql_insert_id()獲取AUTO_INCREMENT列的ID值

mysql_num_fields()獲取結果集中的欄位數

mysql_field_tell()獲取當前欄位位置

mysql_field_seek()定位欄位

mysql_fetch_field()獲取當前欄位

mysql_fetch_field_direct()獲取指定欄位

mysql_frtch_fields()獲取所有欄位的陣列

mysql_num_rows()獲取行數

mysql_fetch_lengths()獲取行長度

mysql_row_tell()獲取當前行位置

mysql_row_seek()行定位

mysql_da ta_seek()行定位

mysql_fetch_row()獲取當前行

第四部分 執行緒類操作函式

mysql_list_processes()返回所有執行緒列表

mysql_thread_id()獲取當前執行緒ID

mysql_thread_safe()是否支援執行緒方式

mysql_kill()殺列一個執行緒

第五部分 出錯處理類函式

mysql_errno()獲取錯誤號

mysql_error()獲取錯誤資訊

第六部分 已過時的函式

mysql_connect()

mysql_create_db()

mysql_drop_db()

mysql_eof()

mysql_reload()

mysql_escape_string()

如果要看函式的具體引數和使用方法也可以參考與libmysql.dll對於的標頭檔案mysql.h,可以在mysql的安裝路徑下搜尋。標頭檔案裡面對每個函式的用途以及每隔引數的含義都有詳細的說明。此外,在網上找別人寫的例子,參考別人使用的程式碼也是瞭解動態庫中函式的使用方法的一種途徑,如http://blog.csdn.net/java2000_net/article/details/4324964

(5)編寫指令碼

下面的指令碼是針對mysql某個表的寫入效能測試的編寫的,此處模擬的業務流程是併發登入mysql資料庫,然後一直往資料庫中寫入資料,寫入100萬條後,退出資料庫的登入。測試的目標是找到該資料庫中某個表寫入記錄數的瓶頸點。為了達到這個效果,此處將資料庫登入的指令碼放在在了Vuser_init模組中,將寫入資料庫的指令碼放在了Action模組中,將退出資料庫登入的指令碼放在了Vuser_end模組中。

Vuser_init:

int rc; 

int db_connection; //資料庫連線

int query_result; // 查詢結果集 MYSQL_RES

char** result_row; // 查詢的資料行

 

char *server = "172.31.27.xx";

char *user = "user";

char *password = "password";

char *database = "ucenter";

int port = 3306;

int unix_socket = NULL; 

int flags = 1; 

vuser_init()

{

    // 找到libmysql.dll的所在位置.如果安裝了mysql,並將dll檔案匯入了指令碼內,可以直接load,不需要路徑

    rc = lr_load_dll("libmysql.dll");

    if (rc != 0) {

    lr_error_message("Could not load libmysql.dll");

     lr_abort();

    }

 

    // 建立MySQL物件

    db_connection = mysql_init(NULL);

    if (db_connection == NULL) {

    lr_error_message("Insufficient memory");

     lr_abort();

    }

    // 連線到MySQL資料庫

    rc = mysql_real_connect(db_connection, server, user, password, database, port, unix_socket, flags);

    if (rc == NULL) {

     lr_error_message("%s", mysql_error(db_connection));

    mysql_close(db_connection);

     lr_abort();

    }

    return 0;

}

Action:

Action()

{

    // 向資料庫插入資料,{NewParam_1}_{NewParam}是引數化之後的引數

    lr_save_string (lr_eval_string("INSERT INTO ismxb_domainipicpstatus

 (service_code, datatype,ip,domain, servicetype, ipfp_status, icpstatus, license,organization, user_id, cur_time, scheme_status)

 VALUES ('56789', '1', '173.36.27.9','{NewParam_1}_{NewParam}', '24', NULL, '1', NULL, NULL, 'admin','2015-12-02 17:54:29', 1)")

                                ,"paramInsertQuery");  

    rc = mysql_query(db_connection, lr_eval_string("{paramInsertQuery}")); 

    if (rc!= 0) { 

    lr_error_message("%s", mysql_error(db_connection)); 

    mysql_close(db_connection); 

    lr_abort(); 

    } 

Vuser_end:

vuser_end()

{

    // 釋放MySQL資源 

    mysql_close(db_connection); 

   

    return 0;

}