当前位置: 首页 > news >正文

游戏网站设计论文影视app开发

游戏网站设计论文,影视app开发,建站都需要什么,安康网站建设小程序一、数据结构和入口函数 1、数据结构 ● page_cleaner_t#xff1a;整个Innodb只有一个#xff0c;包含整个page clean线程相关信息。其中包含了一个page_cleaner_slot_t的指针。变量名含义mutex用于保护整个page_cleaner_t结构体和page_cleaner_slot_t结构体#xff0c;当… 一、数据结构和入口函数 1、数据结构  ●  page_cleaner_t整个Innodb只有一个包含整个page clean线程相关信息。其中包含了一个page_cleaner_slot_t的指针。变量名含义mutex用于保护整个page_cleaner_t结构体和page_cleaner_slot_t结构体当需要修改结构体信息的时候需要获取这个mutex如在pc_request函数中is_requested一个条件变量用于唤醒堵塞在这个条件之上的工作线程is_finished一个条件变量用于通知协调线程刷新工作已经完成n_workers当前存在的工作线程总数requested布尔值当前是否需要进行脏数据刷新工作lsn_limit需要刷新到lsn的位置当需要同步刷新的时候这个值将被赋予以保证小于这个lsn的日志都已经完成了刷盘工作n_slots槽的数量槽的数量和buffer instance的数量相同n_slots_requested当前处于需要刷新状态下(PAGE_CLEANER_STATE_REQUESTED)的槽的数量n_slots_flushing当前处于刷新状态下(PAGE_CLEANER_STATE_FLUSHING)的槽的数量n_slots_finished当前处于已经刷新完成状态下(PAGE_CLEANER_STATE_FINISHED)的槽的数量flush_time整个(以innodb buffer为单位)刷新消耗的时间累计 page_cleaner-flush_time ut_time_ms() - tm;flush_pass整个(以innodb buffer为单位)刷新的次数累计 page_cleaner-flush_pass;slots指针指向实际的槽is_running布尔值如果关闭innodb会被设置为false进行强行刷新脏数据 ●  page_cleaner_slot_t每个buffer instance都包含一个这样的结构体page clean工作线程刷新的时候每个线程都会轮询的检测每个槽直到找到没有被其他page clean线程刷新的槽进行刷新工作或者所有的槽buffer instance 都刷新完成为止。参考pc_flush_slot函数。变量名含义state状态PAGE_CLEANER_STATE_REQUESTED、PAGE_CLEANER_STATE_FLUSHING和PAGE_CLEANER_STATE_FINISHED中的一种n_pages_requested本槽需要刷新的总的块数量n_flushed_list已经刷新的块数succeeded_list布尔值刷新是否完成flush_list_time本槽刷新消耗的时间累计参考pc_flush_slot函数flush_list_pass本槽进行刷新操作的次数累计参考pc_flush_slot函数2、入口函数  ●  协调工作线程入口buf_flush_page_cleaner_coordinator ●  工作线程入口buf_flush_page_cleaner_worker 二、主循环解析 其由函数buf_flush_page_cleaner_coordinator实现。实际正常运行情况下的工作都包含在while (srv_shutdown_state SRV_SHUTDOWN_NONE) 这个大循环下。 1、是否需要睡眠1秒判断 首先如果没有活跃的change buffer 并且没有pending的物理块并且上次刷新的块数量不为0则不需要睡眠1秒源码总有如下解释 /* The page_cleaner skips sleep if the server is idle and there are no pending IOs in the buffer pool and there is work to do. */ if (srv_check_activity(last_activity) || buf_get_n_pending_read_ios() ret_sleep pc_sleep_if_needed( || n_flushed 0){ if (srv_shutdown_state ! SRV_SHUTDOWN_NONE) { next_loop_time, sig_count); //睡眠一秒 break; } } else if (ut_time_ms() next_loop_time) { //如果当前时间大于 上次刷新 时间1 秒则 设置为OS_SYNC_TIME_EXCEEDED ret_sleep OS_SYNC_TIME_EXCEEDED; } else { ret_sleep 0; } 但是这个睡眠是可以被唤醒的比如同步刷新应该就会唤醒它buf_flush_request_force函数。参考函数os_event::wait_time_low 2、IO能力不足警告 如前文所描述这里产生如下警告 page_cleaner: 1000ms intended loop took **ms. The settings might not be optimal.((flushed** , during the time.) 源码片段 if (curr_time next_loop_time 3000) { //如果刷新时间 大于了 上次时间 1 秒3 秒 则报info if (warn_count 0) { ib::info() page_cleaner: 1000ms ms. The settings might not intended loop took 1000 curr_time - next_loop_time if (warn_interval 300) { be optimal. (flushed n_flushed_last , during the time.); } warn_interval 600; } else { warn_interval * 2; 3、同步刷新判断  ●  触发条件 (ret_sleep ! OS_SYNC_TIME_EXCEEDED srv_flush_sync buf_flush_sync_lsn 0) 同步会唤醒正在睡眠状态的page clean协调工作线程那么睡眠应该不会满足一秒的条件所以不会被标记为OS_SYNC_TIME_EXCEEDED同时srv_flush_sync和buf_flush_sync_lsn均会被设置接下来就是唤醒工作线程进行刷新同时本协调线程也完成部分任务。  ●  工作代码 pc_request(ULINT_MAX, lsn_limit); //唤醒page clean 工作线程干活 /* Coordinator also treats requests */ //协调者同样要完成部分任务 while (pc_flush_slot() 0) {}  ●  唤醒操作如前文描述在checkpoint或者DML语句执行过程中都会通过log_free_check检查是否redo log处于安全的状态如果不安全就会调用如下代码log_preflush_pool_modified_pages函数中唤醒page clean线程进行同步刷新 if (srv_flush_sync) { /* wake page cleaner for IO burst */ buf_flush_request_force(new_oldest); //设置全局变量同时通过broadcast唤醒同步刷新 } buf_flush_wait_flushed(new_oldest); //所有线程等待同步刷新完成 4、活跃刷新  ●  触发条件srv_check_activity(last_activity) 这里判断是否有活跃的线程所谓活跃就是调用srv_inc_activity_count函数进行增加的一般来讲DML和DDL会标记为活跃purge线程及其工作线程工作期间会标记为活跃。可以将断点做到srv_inc_activity_count进行debug。所以线上数据库DML比较多所以一般都会是活跃刷新。  ●  工作代码这里涉及到刷新多少个块计算主要函数为 page_cleaner_flush_pages_recommendation后面在讨论。 n_to_flush page_cleaner_flush_pages_recommendation(lsn_limit, last_pages); //此处n_to_flush就是本次需要刷新的块数的数量 /* Coordinator also treats requests */ //工作协调线程同样要完成部分任务 pc_request(n_to_flush, lsn_limit); //唤醒page clean 工作线程干活 pc_wait_finished(n_flushed_list);//等待其他刷新完成 while (pc_flush_slot() 0) {} 5、空闲刷新  ●  触发条件else if (ret_sleep OS_SYNC_TIME_EXCEEDED) 当睡足了1秒并且没有活跃的线程。那么就进行空闲刷新一般来讲如果没有DML/DDL等语句那么应该进行是空闲刷新。  ●  工作代码 buf_flush_lists(PCT_IO(100), LSN_MAX, n_flushed); //io能力 刷新到那个lsn 以及传出刷新的块数量 //PCT_IO是一个宏如下 #define PCT_IO(p) ((ulong) (srv_io_capacity * ((double) (p) / 100.0))) 可以看到这里的百分比直接是100%及按照innodb_io_capacity参数的设定进行刷新。 当然这里只是看了正常期间工作的代码如果是Innodb shutdown也会触发同步刷新。可自行参考代码。 三、page_cleaner_flush_pages_recommendation函数 前面提过这个函数是活跃刷新刷新块的计算函数下面直接给出整个代码 { cur_lsn log_get_lsn();//获取当前的lsn 在 redo buffer中的 if (prev_lsn 0) { //静态变量如果是0则代表是第一次执行本函数 prev_time ut_time(); //获取当前时间 /* First time around. */ prev_lsn cur_lsn; return(0); } sum_pages last_pages_in; if (prev_lsn cur_lsn) { //如果没有redo日志生成 return(0); } time_t curr_time ut_time(); ((static_castdouble(sum_pages) double time_elapsed difftime(curr_time, prev_time); avg_page_rate static_castulint( / time_elapsed) /* How much LSN we have generated since last call. */ avg_page_rate) / 2); //算出上次刷新每秒刷新的pages数量同时加上次计算的每秒平均刷新块数 然后除以2 得到一个每秒刷新的pages数量 第一个计算条件avg_page_rate 生成 lsn_rate static_castlsn_t( static_castdouble(cur_lsn - prev_lsn) / time_elapsed);//计算redo lsn生成率 ulint flush_pass page_cleaner-flush_pass; lsn_avg_rate (lsn_avg_rate lsn_rate) / 2;//计算redo每秒平均生成率 /* aggregate stats of all slots */ mutex_enter(page_cleaner-mutex); ulint flush_tm page_cleaner-flush_time; page_cleaner-flush_time 0; page_cleaner-flush_pass 0; ulint list_tm 0; mutex_exit(page_cleaner-mutex); ulint list_pass 0; for (ulint i 0; i page_cleaner-n_slots; i) {//扫描所有的槽 page_cleaner_slot_t* slot; slot page_cleaner-slots[i]; list_tm slot-flush_list_time; list_pass slot-flush_list_pass; slot-flush_list_time 0; slot-flush_list_pass 0; } pct_for_lsn af_get_pct_for_lsn(age);//计算出lsn的比率 百分比(l列如4.5) oldest_lsn buf_pool_get_oldest_modification(); //获取flush list中最老的ls ut_ad(oldest_lsn log_get_lsn());//断言 age cur_lsn oldest_lsn ? cur_lsn - oldest_lsn : 0; //获取当前LSN和最老LSN的之间的差值 pct_for_dirty af_get_pct_for_dirty(); //计算出一个刷新百分比 (比如100) !!!!重点 pct_total ut_max(pct_for_dirty, pct_for_lsn);//取他们的大值 buf_pool_t* buf_pool buf_pool_from_array(i); /* Estimate pages to be flushed for the lsn progress *///计算target_lsn ulint sum_pages_for_lsn 0; lsn_t target_lsn oldest_lsn lsn_avg_rate * buf_flush_lsn_scan_factor; //计算下一次刷新的 目标lsn 及target_lsnbuf_flush_lsn_scan_factor是定值3 for (ulint i 0; i srv_buf_pool_instances; i) {//循环整个buffer instance找到小于target_lsn的脏块 ulint pages_for_lsn 0; sum_pages_for_lsn pages_for_lsn; //这里汇总所有 innodb buffer实例中 flush list 小于这个 target lsn 的 page 总数 buf_flush_list_mutex_enter(buf_pool); for (buf_page_t* b UT_LIST_GET_LAST(buf_pool-flush_list);//每个innodb buffer的末尾的flush list 进行扫描头插法? b ! NULL; b UT_LIST_GET_PREV(list, b)) { if (b-oldest_modification target_lsn) { break; } pages_for_lsn; //某个 innodb buffer 实例中 flush list 小于这个 target lsn 的 page计数 } buf_flush_list_mutex_exit(buf_pool); /* Cap the maximum IO capacity that we are going to use by mutex_enter(page_cleaner-mutex); ut_ad(page_cleaner-slots[i].state PAGE_CLEANER_STATE_NONE);//断言所有的槽处于没有刷新状态 page_cleaner-slots[i].n_pages_requested pages_for_lsn / buf_flush_lsn_scan_factor 1; //确认槽的n_pages_requested值 mutex_exit(page_cleaner-mutex); } sum_pages_for_lsn / buf_flush_lsn_scan_factor;//buf_flush_lsn_scan_factor为定值3 n_pages (n_pages avg_page_rate pages_for_lsn) / 3; // 3部分组成 1、根据参数计算出来的IO能力 2、以往每秒刷新页的数量 3、根据target lsn 计算出来的一个需要刷新的块数 max_io_capacity. Limit the value to avoid too quick increase */ n_pages PCT_IO(pct_total); //根据 前面得到的 pct_total 和 srv_io_capacity参数得到 刷新的块数 !!!第二个计算参数生成。 if (age log_get_max_modified_age_async()) { //如果日质量小于 异步刷新的范畴 ulint pages_for_lsn std::minulint(sum_pages_for_lsn, srv_max_io_capacity * 2); //即便是需要刷新的块数很多最多只能刷max_io_capacity*2的数量!!!第三个计算参数生成 } if (n_pages srv_max_io_capacity) { } n_pages srv_max_io_capacity; } return(n_pages); 此函数最后计算出了需要刷新的块其中刷新比率计算的的重点函数为af_get_pct_for_dirty和af_get_pct_for_lsn 下面将给出代码注释其实前文中的算法就来自af_get_pct_for_dirty。 四、af_get_pct_for_dirty和af_get_pct_for_lsn函数  ●  af_get_pct_for_dirty函数 double dirty_pct buf_get_modified_ratio_pct(); //得到 修改的块/总的块的 的百分比 记住脏数据比率 if (dirty_pct 0.0) { /* No pages modified */ return(0); } if (srv_max_dirty_pages_pct_lwm 0) { //如果innodb_max_dirty_pages_pct_lwm没有设置 ut_a(srv_max_dirty_pages_pct_lwm srv_max_buf_pool_modified_pct); if (dirty_pct srv_max_buf_pool_modified_pct) { //如果脏数据比率大于了innodb_max_dirty_pages_pct则返回比率100% /* The user has not set the option to preflush dirty pages as we approach the high water mark. */ return(100); /* We have crossed the high water mark of dirty pages In this case we start flushing at 100% of innodb_io_capacity. */ } /* We should start flushing pages gradually. */ //innodb_max_dirty_pages_pct_lwm参数设置 } else if (dirty_pct srv_max_dirty_pages_pct_lwm) { //如果设置了innodb_max_dirty_pages_pct_lwm 并且脏数据比率大于了 return(static_castulint((dirty_pct * 100) return(0);//否则返回0 / (srv_max_buf_pool_modified_pct 1))); //则返回 (脏数据比率/(innodb_max_dirty_pages_pct1))*100 也是一个比率 如(45/76)*100 }  ●  af_get_pct_for_lsn函数注意innodb_cleaner_lsn_age_factor参数默认设置为high_checkpoint可以看到算法最后是除以700.5所有前文我说这个函数算出来的比率一般比较小。 if (age max_async_age !srv_adaptive_flushing) { //如果小于异步刷新 且 自适应flush 没有开启 /* We have still not reached the max_async point and /* If we are here then we know that either: the user has disabled adaptive flushing. */ return(0); } 2) User may have disabled adaptive flushing but we have reached 1) User has enabled adaptive flushing max_async_age. */ lsn_age_factor (age * 100) / max_async_age; //比率lsn_age_factor (本次刷新的日志量/(logtotalsize*(9/10)*(7/8))) ut_ad(srv_max_io_capacity srv_io_capacity); switch ((srv_cleaner_lsn_age_factor_t)srv_cleaner_lsn_age_factor) { case SRV_CLEANER_LSN_AGE_FACTOR_LEGACY: case SRV_CLEANER_LSN_AGE_FACTOR_HIGH_CHECKPOINT: //innodb_cleaner_lsn_age_factor参数默认设置为high_checkpoint return(static_castulint( ((srv_max_io_capacity / srv_io_capacity) * (lsn_age_factor * sqrt((double)lsn_age_factor))) / 7.5)); //430 return(static_castulint( * (lsn_age_factor * lsn_age_factor //(10 * (3.3*10*10))/700 4.3 ((srv_max_io_capacity / srv_io_capacity) // ((max_io_cap /io_cap) * (sqrt(lsn_age_factor)*lsn_age_factor*lsn_age_factor))/700.5 * sqrt((double)lsn_age_factor))) / 700.5)); // 五、总结 本文只是解释了对于page clean线程的结构和刷新方式但是真正的刷新工作实际上从pc_flush_slot函数调用才开始后面非常复杂。 原文发布时间为2018-11-14 本文作者重庆八怪 本文来自云栖社区合作伙伴“老叶茶馆”了解相关信息可以关注“老叶茶馆”。
http://www.pierceye.com/news/703069/

相关文章:

  • 简述网站制作过程企业网络推广网站建设
  • 外贸营销网站建设介绍wordpress分库技术
  • 做竞品分析的网站安卓小程序开发入门
  • 做网站的外包公司可以进吗做旅游网站赚钱吗
  • 网站网页设计基本理论教育学校网站源码 php
  • 吉林省建设厅网站专家新华社官网
  • 代做吧机械网站天津建站管理系统价格
  • 开发网站公司都需要什么岗位人员有了网站怎么写文章
  • 白水网站建设郑州网站推广优化公司
  • 做网站的参考文献专业建设报告
  • asp网站搭建工具中英文网站前端怎么做
  • 微信公众号 做不了微网站wordpress怎么转移
  • 主营网站开发游戏推广员每天做什么
  • c 做网站用什么框架长沙网络建设的网站
  • 专业的网站建设网络网站连接跳转怎么做
  • 南山网站设计方案安徽六安特产
  • 设计型网站案例深圳广告投放公司
  • 能源网站模板头条发布视频成功显示404
  • 郑州网站制作企业建设网站多长时间
  • 建站网站知乎wordpress面包屑
  • 用CMS做网站的好处网站流量消耗计算
  • asp 网站 模板网站建设的公司选择哪家好
  • 广州市越秀区建设局网站字体logo设计在线生成
  • 展示网站模版源码软件开发工具包sdk
  • 佛山网站建站网站程序免费下载
  • 课程设计报告 网站开发网络营销代运营外包公司
  • 手机html5网站模板网站怎么做查询功能
  • 有哪些做外贸的网站可做笔记的阅读网站
  • vs2010c 做网站无锡网站制作有哪些
  • 网站建设安全方案永康公司网站建设