handlersocket源码部分求解
AZ-直到世界的尽头
《MongoDB游记》作者
领域专家: 后端开发技术领域 2013-11-30 11:55:08 用handlersocket(一个对mysql数据库做高速操作的插件)的时候报错 由于网上资料很少 只能去看源码 有没有C C++大神帮忙看看是什么意思
报的错误是 1 lock_tables
void
dbcontext::cmd_insert_internal(dbcallback_i& cb, const prep_stmt& pst,
const string_ref *fvals, size_t fvalslen)
{
if (!for_write_flag) {
return cb.dbcb_resp_short(2, "readonly");
}
lock_tables_if();
if (lock == 0) {
return cb.dbcb_resp_short(1, "lock_tables");
}
if (pst.get_table_id() >= table_vec.size()) {
return cb.dbcb_resp_short(2, "tblnum");
}
TABLE *const table = table_vec[pst.get_table_id()].table;
handler *const hnd = table->file;
uchar *const buf = table->record[0];
empty_record(table);
memset(buf, 0, table->s->null_bytes); /* clear null flags */
const prep_stmt::fields_type& rf = pst.get_ret_fields();
const size_t n = rf.size();
for (size_t i = 0; i < n; ++i) {
uint32_t fn = rf[i];
Field *const fld = table->field[fn];
if (fvals[i].begin() == 0) {
fld->set_null();
} else {
fld->store(fvals[i].begin(), fvals[i].size(), &my_charset_bin);
}
}
table->next_number_field = table->found_next_number_field;
/* FIXME: test */
const int r = hnd->ha_write_row(buf);
const ulonglong insert_id = table->file->insert_id_for_cur_row;
table->next_number_field = 0;
table_vec[pst.get_table_id()].modified = true;
if (r == 0 && table->found_next_number_field != 0) {
return cb.dbcb_resp_short_num64(0, insert_id);
}
if (r != 0) {
return cb.dbcb_resp_short_num(1, r);
}
return cb.dbcb_resp_short(0, "");
}
lock_tables_if() 的定义为:
virtual void lock_tables_if();
变量定义:
private:
volatile database *const dbref;
bool for_write_flag;
THD *thd;
MYSQL_LOCK *lock;
bool lock_failed;
std::auto_ptr<expr_user_lock> user_lock;
int user_level_lock_timeout;
bool user_level_lock_locked;
bool commit_error;
std::vector<char> info_message_buf;
table_vec_type table_vec;
table_map_type table_map;
具体实现:
void
dbcontext::lock_tables_if()
{
if (lock_failed) {
return;
}
if (for_write_flag && !user_level_lock_locked) {
if (user_lock->get_lock()) {
user_level_lock_locked = true;
} else {
lock_failed = true;
return;
}
}
if (lock == 0) {
const size_t num_max = table_vec.size();
TABLE **const tables = DENA_ALLOCA_ALLOCATE(TABLE *, num_max + 1);
size_t num_open = 0;
for (size_t i = 0; i < num_max; ++i) {
if (table_vec[i].refcount > 0) {
tables[num_open++] = table_vec[i].table;
}
table_vec[i].modified = false;
}
#if MYSQL_VERSION_ID >= 50505
lock = thd->lock = mysql_lock_tables(thd, &tables[0], num_open, 0);
#else
bool need_reopen= false;
lock = thd->lock = mysql_lock_tables(thd, &tables[0], num_open,
MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN, &need_reopen);
#endif
statistic_increment(lock_tables_count, &LOCK_status);
thd_proc_info(thd, &info_message_buf[0]);
DENA_VERBOSE(100, fprintf(stderr, "HNDSOCK lock tables %p %p %zu %zu\n",
thd, lock, num_max, num_open));
if (lock == 0) {
lock_failed = true;
DENA_VERBOSE(10, fprintf(stderr, "HNDSOCK failed to lock tables %p\n",
thd));
}
if (for_write_flag) {
#if MYSQL_VERSION_ID >= 50505
thd->set_current_stmt_binlog_format_row();
#else
thd->current_stmt_binlog_row_based = 1;
#endif
}
DENA_ALLOCA_FREE(tables);
}
DBG_LOCK(fprintf(stderr, "HNDSOCK tblnum=%d\n", (int)tblnum));
}
据说
对表加锁,调用的是mysql的
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags)
表解锁
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
大神们帮看看代码 分析下 return cb.dbcb_resp_short(1, "lock_tables"); 的原因有哪些
谢谢大家了。
源码地址:
http://handlersocket.sourcearchive.com/documentation/1.0.6-80-g88bf1e0-1/database_8cpp_source.html