• postgresql源码学习(39)—— 崩溃恢复① - Startup进程的三大作用


    如果数据库宕机或者服务器故障,缓存中的脏页可能尚未被刷入磁盘,磁盘中的数据处于不一致状态。在数据库重新启动时,需要借助WAL日志将数据库恢复到一致的状态。

    • Startup进程的三大作用

    崩溃恢复的核心进程是Startup进程,核心函数是StartupXLOG函数,它在pg启动时就会被调用,读取配置信息,应用WAL日志。

    通过读取不同参数,Startup进程可以完成3大功能——崩溃恢复、从库日志应用、PITR(基于时间点的恢复)。可以看到,这3大功能与WAL日志应用都是分不开的。

    二、 配置信息读取

    1. 判断方式

    用户可以在数据目录下创建standby.signal或者recovery.signal文件,Startup进程会检查这两个文件是否存在:

    1. 若都不存在,执行普通的崩溃恢复,应用到最新日志
    2. 若standby.signal存在,则当前数据库是个从库,持续进行日志应用
    3. 若recovery.signal文件存在,则进行PITR操作,根据recovery_target应用日志。注意从pg 12开始已经不再支持recovery.conf文件,如果检测到会报错。

    1. readRecoverySignalFile函数
    1. /*
    2. * See if there are any recovery signal files and if so, set state for
    3. * recovery.
    4. *
    5. * See if there is a recovery command file (recovery.conf), and if so
    6. * throw an ERROR since as of PG12 we no longer recognize that.
    7. */
    8. static void
    9. readRecoverySignalFile(void)
    10. {
    11. struct stat stat_buf;
    12. if (IsBootstrapProcessingMode())
    13. return;
    14. /*
    15. * Check for old recovery API file: recovery.conf,检查recovery.conf文件,如果有则报错
    16. */
    17. if (stat(RECOVERY_COMMAND_FILE, &stat_buf) == 0)
    18. ereport(FATAL,
    19. (errcode_for_file_access(),
    20. errmsg("using recovery command file \"%s\" is not supported",
    21. RECOVERY_COMMAND_FILE)));
    22. /*
    23. * Remove unused .done file, if present. Ignore if absent.如果存在.done文件,将其删除
    24. */
    25. unlink(RECOVERY_COMMAND_DONE);
    26. /* 若standby.signal存在,将standby_signal_file_found标签设置为true,说明当前数据库是个从库 */
    27. if (stat(STANDBY_SIGNAL_FILE, &stat_buf) == 0)
    28. {
    29. int fd;
    30. fd = BasicOpenFilePerm(STANDBY_SIGNAL_FILE, O_RDWR | PG_BINARY | get_sync_bit(sync_method),
    31. S_IRUSR | S_IWUSR);
    32. if (fd >= 0)
    33. {
    34. (void) pg_fsync(fd);
    35. close(fd);
    36. }
    37. standby_signal_file_found = true;
    38. }
    39. /* 若recovery.signal存在,将recovery_signal_file_found标签设置为true,说明当前在执行PITR */
    40. else if (stat(RECOVERY_SIGNAL_FILE, &stat_buf) == 0)
    41. {
    42. int fd;
    43. fd = BasicOpenFilePerm(RECOVERY_SIGNAL_FILE, O_RDWR | PG_BINARY | get_sync_bit(sync_method),
    44. S_IRUSR | S_IWUSR);
    45. if (fd >= 0)
    46. {
    47. (void) pg_fsync(fd);
    48. close(fd);
    49. }
    50. recovery_signal_file_found = true;
    51. }
    52. /* 如果都不是,将下面两个参数设置为false */
    53. StandbyModeRequested = false;
    54. ArchiveRecoveryRequested = false;
    55. if (standby_signal_file_found)
    56. {
    57. StandbyModeRequested = true;
    58. ArchiveRecoveryRequested = true;
    59. }
    60. else if (recovery_signal_file_found)
    61. {
    62. StandbyModeRequested = false;
    63. ArchiveRecoveryRequested = true;
    64. }
    65. else
    66. /* 如果都不是,直接返回,说明是普通的崩溃恢复 */
    67. return;
    68. /*
    69. * We don't support standby mode in standalone backends; that requires other processes such as the WAL receiver to be alive.
    70. */
    71. if (StandbyModeRequested && !IsUnderPostmaster)
    72. ereport(FATAL,
    73. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    74. errmsg("standby mode is not supported by single-user servers")));
    75. }

    下一篇,我们正式学习StartupXLOG函数,看不同场景下如何进行日志应用。

    参考

    《PostgreSQL技术内幕:事务处理深度探索》第4章

  • 相关阅读:
    Jetpack Compose学习(11)——Navigation页面导航的使用
    Morgan Stanley面经
    准备创建独立站?2022年最新制作企业官网必看的网页设计全攻略
    Springboot-‘@Getter‘ not applicable to type,报错是因为没有引用lombok依赖
    springboot logback-spring.xml 整合apollo实现动态配置日志级别
    SARAS-Net: Scale and Relation Aware Siamese Network for Change Detection
    Linux中固定ip端口和修改ip地址
    如何解决 npm ERR! Cannot read properties of null (reading ‘pickAlgorithm‘)报错问题
    speedoffice(Word)怎么修改字体颜色呢
    一种基于E3处理器平台的NAS完整方案(从电脑组装到网站部署)
  • 原文地址:https://blog.csdn.net/Hehuyi_In/article/details/126330286