博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL内核技术之“pthead局部变量”
阅读量:6878 次
发布时间:2019-06-26

本文共 3745 字,大约阅读时间需要 12 分钟。

MySQL使用了称之为psi/pfs的一系列文件和结构来进行performance监控。Psi全称为performance schema interface,pfs全称为performance storage。

该机制使用pthead来进行操作,其首先定义了pthread的线程存储变量(pfs.cc):

thread_local_key_t THR_PFS;thread_local_key_t THR_PFS_VG;   // global_variablesthread_local_key_t THR_PFS_SV;   // session_variablesthread_local_key_t THR_PFS_VBT;  // variables_by_threadthread_local_key_t THR_PFS_SG;   // global_statusthread_local_key_t THR_PFS_SS;   // session_statusthread_local_key_t THR_PFS_SBT;  // status_by_threadthread_local_key_t THR_PFS_SBU;  // status_by_userthread_local_key_t THR_PFS_SBH;  // status_by_hostthread_local_key_t THR_PFS_SBA;  // status_by_accountbool THR_PFS_initialized= false;

这里的thread_local_key_t实际上是pthread_key_t,即pthread线程存储变量。pthread_key_t的使用就像一个全局变量,哪个线程都可以用,但是实际上对应了线程内部的变量值,可以参见该例:。pthread规定,线程存储变量thread_local_key_t必须要先初始化。MySQL在pfs_server.cc中对这些变量统一初始化:

void pre_initialize_performance_schema(){  pfs_initialized= false;  init_all_builtin_memory_class();  PFS_table_stat::g_reset_template.reset();  global_idle_stat.reset();  global_table_io_stat.reset();  global_table_lock_stat.reset();  if (my_create_thread_local_key(&THR_PFS, destroy_pfs_thread))    return;  if (my_create_thread_local_key(&THR_PFS_VG, NULL))  // global_variables    return;  if (my_create_thread_local_key(&THR_PFS_SV, NULL))  // session_variables    return;  if (my_create_thread_local_key(&THR_PFS_VBT, NULL)) // variables_by_thread    return;  if (my_create_thread_local_key(&THR_PFS_SG, NULL))  // global_status    return;  if (my_create_thread_local_key(&THR_PFS_SS, NULL))  // session_status    return;  if (my_create_thread_local_key(&THR_PFS_SBT, NULL)) // status_by_thread    return;  if (my_create_thread_local_key(&THR_PFS_SBU, NULL)) // status_by_user    return;  if (my_create_thread_local_key(&THR_PFS_SBH, NULL)) // status_by_host    return;  if (my_create_thread_local_key(&THR_PFS_SBA, NULL)) // status_by_account    return;  THR_PFS_initialized= true;}

注意,这个初始化只做一次,以后创建线程时直接使用即可。上的第一个变量THR_PFS就是我们要使用的。

如何使用

使用上的方式初始化,首先要set相应的value:

/**  @brief Execute the JOIN generated by parallel  @param join [in] JOIN structure*/void execute_join(parallel_execution_thread_arg* parallel_arg) {    /*     * Get the parameter:     * 1. JOIN     * 2. pfs     */    /// TODO: do we need to handle error?    std::cout << "****************I am in worker thread*****************" << std::endl;    /// Get join    JOIN* join= parallel_arg->join;    /// Get and Set pfs    PSI_thread* pfs= parallel_arg->pfs;    pfs_set_thread_v1(pfs);    /// Delete    delete parallel_arg;        /// Set the new thread context    my_thread_set_THR_THD(join->thd);    /// Execute    join->exec();}

上面的函数是我在MySQL中新加入的代码,其中使用pfs_set_thread_v1进行set操作,即把当前THR_PFS对应的值设置为pfs。

get操作。由于我们加入了boost线程库,所以当启动一个线程时需要把JOIN结构和pfs结构传入。思路是首先通过THR_PFS获得pfs线程句柄,作为参数传入到新的线程中。再新线程执行函数中,把pfs线程句柄set进去。具体在sql_select.cc中,我们加入了如下代码:

/**  Parallel execution.  @details When a JOIN is parallel, its JOINs will execute parallelly.  Put all JOINs into thread pool to execute.*/void JOIN::parallel_exec_joins() {  for (uint i= 0; i < m_parallel_joins.size(); i ++) {    /// Delete it in join->exec    parallel_execution_thread_arg* parallel_arg= new parallel_execution_thread_arg();    /// Set join    JOIN* join= m_parallel_joins[i];    parallel_arg->join= join;    /// Set pfs    PSI_thread* pfs= pfs_get_thread_v1();    parallel_arg->pfs= pfs;    /// Thread pool    generic_thread_pool.SubmitTask(execute_join, (parallel_execution_thread_arg* &&)parallel_arg);  }}

可以看到,我们通过MySQL的pfs_get_thread_v1获得pfs线程句柄传入到新的线程。

上面的例子是针对pfs的线程。对于MySQL普通线程的例子在上面的execute_join也能找到。注意里面有一行code:

/// Set the new thread contextmy_thread_set_THR_THD(join->thd);

这里就是把当前的thd设置到pthread中。所以我们看到,在MySQL中的很多地方都用到了这个东西,用法也已经明确了。

转载地址:http://hjgfl.baihongyu.com/

你可能感兴趣的文章
如何利用业余时间快乐的赚钱
查看>>
站长福利:网站内容设置扫码打赏后才能看啦!
查看>>
如何快速有效的提高新站权重
查看>>
Cisco设备作为DHCP服务器的配置方法(下)
查看>>
戴尔Windows 8终端:办公、娱乐两不误
查看>>
一体化解决方案是一条正确的发展道路
查看>>
Java中final和static关键字总结
查看>>
Oracle11.2.0.4-Rac集群hang分析记录
查看>>
Objective-C中init函数实现的相关研究
查看>>
java中重载与重写的区别
查看>>
Powerdesigner数据库建模--概念模型--ER图
查看>>
Rss内容读取
查看>>
解决Xcode 代码颜色不显示
查看>>
java 的继承,深入理解
查看>>
一个强大的人民币大写转换的正则表达式
查看>>
MySQL索引背后的数据结构及算法原理zz
查看>>
用代码实现Sharepoint2010的个人信息的照片上传(原创)
查看>>
MF前传——探索者一号简介
查看>>
HDU 3681 Prison Break
查看>>
Spring-模板方法模式及Callback
查看>>