Hi Monty, Thanks for the fix. We will add the changes to PBXT shortly. Best regards, Paul On Jan 6, 2010, at 9:05 PM, Michael Widenius wrote:
Hi!
Here is part from a patch that I will push today to MariaDB-5.1-release that fixes so that pbxt compiles on OpenSolaris 5.11.
Issues fixed:
- lock_multi.test was not updated to latest release main.lock_multi.test and still relied on sleep, which caused random failures. Fixed by merging with main.lock_multi.test - thr_main() was declared in /usr/include/thread.h and caused a name conflict. Fixed by renaming it to thr_main_pbxt()
Hope you can add this to pbxt ASAP!
Regards, Monty
=== modified file 'mysql-test/suite/pbxt/r/lock_multi.result' --- mysql-test/suite/pbxt/r/lock_multi.result 2009-04-02 10:03:14 +0000 +++ mysql-test/suite/pbxt/r/lock_multi.result 2010-01-06 12:18:02 +0000 @@ -1,22 +1,4 @@ drop table if exists t1,t2; -create table t1(n int); -insert into t1 values (1); -lock tables t1 write; -update low_priority t1 set n = 4; -select n from t1; -unlock tables; -n -1 -drop table t1; -create table t1(n int); -insert into t1 values (1); -lock tables t1 read; -update low_priority t1 set n = 4; -select n from t1; -unlock tables; -n -1 -drop table t1; create table t1 (a int, b int); create table t2 (c int, d int); insert into t1 values(1,1); @@ -43,6 +25,7 @@ insert t1 select * from t2; drop table t2; ERROR 42S02: Table 'test.t2' doesn't exist drop table t1; +End of 4.1 tests create table t1(a int); lock tables t1 write; show columns from t1; @@ -50,10 +33,10 @@ Field Type Null Key Default Extra a int(11) YES NULL unlock tables; drop table t1; -use mysql; +USE mysql; LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE; FLUSH TABLES; -use mysql; +USE mysql; SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1; OPTIMIZE TABLES columns_priv, db, host, user; Table Op Msg_type Msg_text @@ -63,7 +46,8 @@ mysql.host optimize status OK mysql.user optimize status OK UNLOCK TABLES; Select_priv -use test; +N +USE test; use test; CREATE TABLE t1 (c1 int); LOCK TABLE t1 WRITE; @@ -90,7 +74,115 @@ DROP DATABASE mysqltest_1; ERROR HY000: Can't drop database 'mysqltest_1'; database doesn't exist create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb; lock tables t1 write; -alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // -alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // +alter table t1 auto_increment=0; +alter table t1 auto_increment=0; +unlock tables; +drop table t1; +create table t1 (a int); +create table t2 like t1; +# con1 +lock tables t1 write; +# con2 +flush tables with read lock; +# con5 +# global read lock is taken +# con3 +select * from t2 for update; +# waiting for release of read lock +# con4 +# would hang and later cause a deadlock +flush tables t2; +# clean up +unlock tables; +unlock tables; +a +drop table t1,t2; +# +# Lightweight version: +# Ensure that the wait for a GRL is done before opening tables. +# +create table t1 (a int); +create table t2 like t1; +# +# UPDATE +# +# default +flush tables with read lock; +# con1 +update t2 set a = 1; +# default +# statement is waiting for release of read lock +# con2 +flush table t2; +# default +unlock tables; +# con1 +# +# LOCK TABLES .. WRITE +# +# default +flush tables with read lock; +# con1 +lock tables t2 write; +# default +# statement is waiting for release of read lock +# con2 +flush table t2; +# default +unlock tables; +# con1 +unlock tables; +drop table t1,t2; +End of 5.0 tests +create table t1 (i int); +lock table t1 read; +update t1 set i= 10; +select * from t1; +Timeout in wait_condition.inc for select count(*) = 1 from information_schema.processlist +where state = "Locked" and info = "select * from t1" +kill query ID; +i +ERROR 70100: Query execution was interrupted +unlock tables; +drop table t1; +drop table if exists t1; +create table t1 (i int); +connection: default +lock tables t1 write; +connection: flush +flush tables with read lock;; +connection: default +alter table t1 add column j int; +connection: insert +insert into t1 values (1,2);; +connection: default +unlock tables; +connection: flush +select * from t1; +i j +unlock tables; +select * from t1; +i j +1 2 +drop table t1; +drop table if exists t1; +create table t1 (i int); +connection: default +lock tables t1 write; +connection: flush +flush tables with read lock;; +connection: default +flush tables; +unlock tables; +drop table t1; +drop table if exists t1,t2; +create table t1 (a int); +flush status; +lock tables t1 read; +insert into t1 values(1);; unlock tables; drop table t1; +select @tlwa < @tlwb; +@tlwa < @tlwb +1 +End of 5.1 tests
=== modified file 'mysql-test/suite/pbxt/t/lock_multi.test' --- mysql-test/suite/pbxt/t/lock_multi.test 2009-04-02 10:03:14 +0000 +++ mysql-test/suite/pbxt/t/lock_multi.test 2010-01-06 12:17:25 +0000 @@ -1,4 +1,8 @@ -- source include/not_embedded.inc + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + --disable_warnings drop table if exists t1,t2; --enable_warnings @@ -9,42 +13,6 @@ connect (locker,localhost,root,,); connect (reader,localhost,root,,); connect (writer,localhost,root,,);
-connection locker; -create table t1(n int); -insert into t1 values (1); -lock tables t1 write; -connection writer; -send update low_priority t1 set n = 4; -connection reader; ---sleep 2 -send select n from t1; -connection locker; ---sleep 2 -unlock tables; -connection writer; -reap; -connection reader; -reap; -drop table t1; - -connection locker; -create table t1(n int); -insert into t1 values (1); -lock tables t1 read; -connection writer; -send update low_priority t1 set n = 4; -connection reader; ---sleep 2 -send select n from t1; -connection locker; ---sleep 2 -unlock tables; -connection writer; -reap; -connection reader; -reap; -drop table t1; - # # Test problem when using locks with multi-updates # It should not block when multi-update is reading on a read-locked table @@ -58,32 +26,33 @@ insert into t1 values(2,2); insert into t2 values(1,2); lock table t1 read; connection writer; ---sleep 2 -send update t1,t2 set c=a where b=d; +update t1,t2 set c=a where b=d; connection reader; ---sleep 2 select c from t2; -connection writer; -reap; connection locker; drop table t1; drop table t2;
# -# Test problem when using locks on many tables and droping a table that +# Test problem when using locks on many tables and dropping a table that # is to-be-locked by another thread # - +# connection locker; create table t1 (a int); create table t2 (a int); lock table t1 write, t2 write; connection reader; -send insert t1 select * from t2; +send +insert t1 select * from t2; connection locker; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "insert t1 select * from t2"; +--source include/wait_condition.inc drop table t2; connection reader; ---error 1146 +--error ER_NO_SUCH_TABLE reap; connection locker; drop table t1; @@ -97,20 +66,26 @@ create table t1 (a int); create table t2 (a int); lock table t1 write, t2 write, t1 as t1_2 write, t2 as t2_2 write; connection reader; -send insert t1 select * from t2; +send +insert t1 select * from t2; connection locker; +# Sleep a bit till the insert of connection reader is in work and hangs +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "insert t1 select * from t2"; +--source include/wait_condition.inc drop table t2; connection reader; ---error 1146 +--error ER_NO_SUCH_TABLE reap; connection locker; drop table t1;
-# End of 4.1 tests +--echo End of 4.1 tests
# -# BUG#9998 - MySQL client hangs on USE "database" +# Bug#9998 MySQL client hangs on USE "database" # create table t1(a int); lock tables t1 write; @@ -121,21 +96,30 @@ unlock tables; drop table t1;
# -# Bug#16986 - Deadlock condition with MyISAM tables +# Bug#16986 Deadlock condition with MyISAM tables # + +# Need a matching user in mysql.user for multi-table select +--source include/add_anonymous_users.inc + connection locker; -use mysql; +USE mysql; LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE; FLUSH TABLES; ---sleep 1 # connection reader; -use mysql; -#NOTE: This must be a multi-table select, otherwise the deadlock will not occur -send SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1; ---sleep 1 +USE mysql; +# Note: This must be a multi-table select, otherwise the deadlock will not occur +send +SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1; # connection locker; +# Sleep a bit till the select of connection reader is in work and hangs +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table" and info = + "SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1"; +--source include/wait_condition.inc # Make test case independent from earlier grants. --replace_result "Table is already up to date" "OK" OPTIMIZE TABLES columns_priv, db, host, user; @@ -143,7 +127,7 @@ UNLOCK TABLES; # connection reader; reap; -use test; +USE test; # connection locker; use test; @@ -158,11 +142,16 @@ LOCK TABLE t1 WRITE; # # This waits until t1 is unlocked. connection locker; -send FLUSH TABLES WITH READ LOCK; ---sleep 1 +send +FLUSH TABLES WITH READ LOCK; # -# This must not block. connection writer; +# Sleep a bit till the flush of connection locker is in work and hangs +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Flushing tables" and info = "FLUSH TABLES WITH READ LOCK"; +--source include/wait_condition.inc +# This must not block. CREATE TABLE t2 (c1 int); UNLOCK TABLES; # @@ -182,12 +171,17 @@ LOCK TABLE t1 WRITE; # # This waits until t1 is unlocked. connection locker; -send FLUSH TABLES WITH READ LOCK; ---sleep 1 +send +FLUSH TABLES WITH READ LOCK; # # This must not block. connection writer; ---error 1100 +# Sleep a bit till the flush of connection locker is in work and hangs +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Flushing tables" and info = "FLUSH TABLES WITH READ LOCK"; +--source include/wait_condition.inc +--error ER_TABLE_NOT_LOCKED CREATE TABLE t2 AS SELECT * FROM t1; UNLOCK TABLES; # @@ -199,8 +193,10 @@ UNLOCK TABLES; connection default; DROP TABLE t1;
+--source include/delete_anonymous_users.inc + # -# Bug#19815 - CREATE/RENAME/DROP DATABASE can deadlock on a global read lock +# Bug#19815 CREATE/RENAME/DROP DATABASE can deadlock on a global read lock # connect (con1,localhost,root,,); connect (con2,localhost,root,,); @@ -212,12 +208,18 @@ FLUSH TABLES WITH READ LOCK; # With bug in place: acquire LOCK_mysql_create_table and # wait in wait_if_global_read_lock(). connection con2; -send DROP DATABASE mysqltest_1; ---sleep 1 +send +DROP DATABASE mysqltest_1; # # With bug in place: try to acquire LOCK_mysql_create_table... # When fixed: Reject dropping db because of the read lock. connection con1; +# Wait a bit so that the session con2 is in state "Waiting for release of readlock" +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for release of readlock" + and info = "DROP DATABASE mysqltest_1"; +--source include/wait_condition.inc --error ER_CANT_UPDATE_WITH_READLOCK DROP DATABASE mysqltest_1; UNLOCK TABLES; @@ -234,7 +236,7 @@ disconnect con2; DROP DATABASE mysqltest_1;
# -# Bug #17264: MySQL Server freeze +# Bug#17264 MySQL Server freeze # connection locker; # Disable warnings to allow test to run also without InnoDB @@ -243,17 +245,22 @@ create table t1 (f1 int(12) unsigned not --enable_warnings lock tables t1 write; connection writer; ---sleep 2 -delimiter //; -send alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // -delimiter ;// -connection reader; ---sleep 2 -delimiter //; -send alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // -delimiter ;// -connection locker; ---sleep 2 +send +alter table t1 auto_increment=0; +connection reader; +# Wait till connection writer is blocked +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "alter table t1 auto_increment=0"; +--source include/wait_condition.inc +send +alter table t1 auto_increment=0; +connection locker; +# Wait till connection reader is blocked +let $wait_condition= + select count(*) = 2 from information_schema.processlist + where state = "Locked" and info = "alter table t1 auto_increment=0"; +--source include/wait_condition.inc unlock tables; connection writer; reap; @@ -262,8 +269,310 @@ reap; connection locker; drop table t1;
+# +# Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely +# + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +connect (con3,localhost,root,,); +connect (con4,localhost,root,,); +connect (con5,localhost,root,,); + +create table t1 (a int); +create table t2 like t1; + +connection con1; +--echo # con1 +lock tables t1 write; +connection con2; +--echo # con2 +send flush tables with read lock; +connection con5; +--echo # con5 +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Flushing tables'; +--source include/wait_show_condition.inc +--echo # global read lock is taken +connection con3; +--echo # con3 +send select * from t2 for update; +connection con5; +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Waiting for release of readlock'; +--source include/wait_show_condition.inc +--echo # waiting for release of read lock +connection con4; +--echo # con4 +--echo # would hang and later cause a deadlock +flush tables t2; +connection con1; +--echo # clean up +unlock tables; +connection con2; +--reap +unlock tables; +connection con3; +--reap +connection default; +disconnect con5; +disconnect con4; +disconnect con3; +disconnect con2; +disconnect con1; + +drop table t1,t2; + +--echo # +--echo # Lightweight version: +--echo # Ensure that the wait for a GRL is done before opening tables. +--echo # + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +create table t1 (a int); +create table t2 like t1; + +--echo # +--echo # UPDATE +--echo # + +connection default; +--echo # default +flush tables with read lock; +connection con1; +--echo # con1 +send update t2 set a = 1; +connection default; +--echo # default +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Waiting for release of readlock'; +--source include/wait_show_condition.inc +--echo # statement is waiting for release of read lock +connection con2; +--echo # con2 +flush table t2; +connection default; +--echo # default +unlock tables; +connection con1; +--echo # con1 +--reap + +--echo # +--echo # LOCK TABLES .. WRITE +--echo # + +connection default; +--echo # default +flush tables with read lock; +connection con1; +--echo # con1 +send lock tables t2 write; +connection default; +--echo # default +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Waiting for release of readlock'; +--source include/wait_show_condition.inc +--echo # statement is waiting for release of read lock +connection con2; +--echo # con2 +flush table t2; +connection default; +--echo # default +unlock tables; +connection con1; +--echo # con1 +--reap +unlock tables; + +connection default; +disconnect con2; +disconnect con1; + +drop table t1,t2; + + +--echo End of 5.0 tests + + +# +# Bug#21281 Pending write lock is incorrectly removed when its +# statement being KILLed +# +create table t1 (i int); +connection locker; +lock table t1 read; +connection writer; +send +update t1 set i= 10; +connection reader; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "update t1 set i= 10"; +--source include/wait_condition.inc +send +select * from t1; +connection default; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "select * from t1"; +--source include/wait_condition.inc +let $ID= `select id from information_schema.processlist where state = "Locked" and info = "update t1 set i= 10"`; +--replace_result $ID ID +eval kill query $ID; +connection reader; +--reap +connection writer; +--error ER_QUERY_INTERRUPTED +--reap +connection locker; +unlock tables; +connection default; +drop table t1; + +# Disconnect sessions used in many subtests above +disconnect locker; +disconnect reader; +disconnect writer; + +# +# Bug#32395 Alter table under a impending global read lock causes a server crash +# + +# +# Test ALTER TABLE under LOCK TABLES and FLUSH TABLES WITH READ LOCK +# + +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (i int); +connect (flush,localhost,root,,test,,); +connection default; +--echo connection: default +lock tables t1 write; +connection flush; +--echo connection: flush +--send flush tables with read lock; +connection default; +--echo connection: default +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Flushing tables"; +--source include/wait_condition.inc +alter table t1 add column j int; +connect (insert,localhost,root,,test,,); +connection insert; +--echo connection: insert +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Flushing tables"; +--source include/wait_condition.inc +--send insert into t1 values (1,2); +--echo connection: default +connection default; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for release of readlock"; +--source include/wait_condition.inc +unlock tables; +connection flush; +--echo connection: flush +--reap +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for release of readlock"; +--source include/wait_condition.inc +select * from t1; +unlock tables; +connection insert; +--reap +connection default; +let $wait_condition= + select count(*) = 1 from t1; +--source include/wait_condition.inc +select * from t1; +drop table t1; +disconnect flush; +disconnect insert; + +# +# Test that FLUSH TABLES under LOCK TABLES protects write locked tables +# from a impending FLUSH TABLES WITH READ LOCK +# + +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (i int); +connect (flush,localhost,root,,test,,); +connection default; +--echo connection: default +lock tables t1 write; +connection flush; +--echo connection: flush +--send flush tables with read lock; +connection default; +--echo connection: default +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Flushing tables"; +--source include/wait_condition.inc +flush tables; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Flushing tables"; +--source include/wait_condition.inc +unlock tables; +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where state = "Flushing tables"; +--source include/wait_condition.inc +connection flush; +--reap +connection default; +disconnect flush; +drop table t1; + +# +# Bug#30331 Table_locks_waited shows inaccurate values +# + +--disable_warnings +drop table if exists t1,t2; +--enable_warnings +create table t1 (a int); +flush status; +lock tables t1 read; +let $tlwa= `show status like 'Table_locks_waited'`; +connect (waiter,localhost,root,,); +connection waiter; +--send insert into t1 values(1); +connection default; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Locked" and info = "insert into t1 values(1)"; +--source include/wait_condition.inc +let $tlwb= `show status like 'Table_locks_waited'`; +unlock tables; +drop table t1; +disconnect waiter; +connection default; --disable_query_log +eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1); +eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1); drop database pbxt; --enable_query_log -# End of 5.0 tests +select @tlwa < @tlwb; + +--echo End of 5.1 tests + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc
=== modified file 'storage/pbxt/src/ha_pbxt.cc' --- storage/pbxt/src/ha_pbxt.cc 2009-12-29 11:34:44 +0000 +++ storage/pbxt/src/ha_pbxt.cc 2010-01-06 17:38:08 +0000 @@ -1294,7 +1294,7 @@ static int pbxt_init(void *p) #6 0x000debe1 in THD::THD at sql_class.cc:631 #7 0x00e207a4 in myxt_create_thread at myxt_xt.cc:2666 #8 0x00e3134b in tabc_fr_run_thread at tabcache_xt.cc:982 - #9 0x00e422ca in thr_main at thread_xt.cc:1006 + #9 0x00e422ca in thr_main_pbxt at thread_xt.cc:1006 #10 0x91ff7c55 in _pthread_start #11 0x91ff7b12 in thread_start * @@ -1557,7 +1557,7 @@ static int pbxt_prepare(handlerton *hton return err; }
-static XTThreadPtr ha_temp_open_global_database(handlerton *hton, THD **ret_thd, int *temp_thread, char *thread_name, int *err) +static XTThreadPtr ha_temp_open_global_database(handlerton *hton, THD **ret_thd, int *temp_thread, const char *thread_name, int *err) { THD *thd; XTThreadPtr self = NULL;
=== modified file 'storage/pbxt/src/restart_xt.cc' --- storage/pbxt/src/restart_xt.cc 2009-11-27 15:37:02 +0000 +++ storage/pbxt/src/restart_xt.cc 2010-01-06 17:38:22 +0000 @@ -3314,7 +3314,7 @@ static void *xn_xres_run_recovery_thread * #7 0x000c0db2 in THD::~THD at sql_class.cc:934 * #8 0x003b025b in myxt_destroy_thread at myxt_xt.cc:2999 * #9 0x003b66b5 in xn_xres_run_recovery_thread at restart_xt.cc:3196 - * #10 0x003cbfbb in thr_main at thread_xt.cc:1020 + * #10 0x003cbfbb in thr_main_pbxt at thread_xt.cc:1020 * myxt_destroy_thread(mysql_thread, TRUE); */
=== modified file 'storage/pbxt/src/thread_xt.cc' --- storage/pbxt/src/thread_xt.cc 2009-12-22 10:33:20 +0000 +++ storage/pbxt/src/thread_xt.cc 2010-01-06 17:37:45 +0000 @@ -1013,7 +1013,7 @@ static xtBool thr_setup_signals(void)
typedef void *(*ThreadMainFunc)(XTThreadPtr self);
-extern "C" void *thr_main(void *data) +extern "C" void *thr_main_pbxt(void *data) { ThreadDataPtr td = (ThreadDataPtr) data; XTThreadPtr self = td->td_thr; @@ -1503,10 +1503,10 @@ xtPublic pthread_t xt_run_thread(XTThrea pthread_attr_t attr = { 0, 0, 0 };
attr.priority = THREAD_PRIORITY_NORMAL; - err = pthread_create(&child_thread, &attr, thr_main, &data); + err = pthread_create(&child_thread, &attr, thr_main_pbxt, &data); } #else - err = pthread_create(&child_thread, NULL, thr_main, &data); + err = pthread_create(&child_thread, NULL, thr_main_pbxt, &data); #endif if (err) { xt_free_thread(child);
=== modified file 'storage/pbxt/src/thread_xt.h' --- storage/pbxt/src/thread_xt.h 2009-11-24 10:55:06 +0000 +++ storage/pbxt/src/thread_xt.h 2010-01-06 17:37:13 +0000 @@ -536,7 +536,7 @@ extern struct XTThread **xt_thr_array; * Function prototypes */
-extern "C" void *thr_main(void *data); +extern "C" void *thr_main_pbxt(void *data);
void xt_get_now(char *buffer, size_t len); xtBool xt_init_logging(void);
-- Paul McCullagh PrimeBase Technologies www.primebase.org www.blobstreaming.org pbxt.blogspot.com