{"id":1226,"date":"2026-07-20T11:40:09","date_gmt":"2026-07-20T08:40:09","guid":{"rendered":"https:\/\/itgen.itbumper.com\/?page_id=1226"},"modified":"2026-07-20T11:43:51","modified_gmt":"2026-07-20T08:43:51","slug":"0053_mobaxterm-macros-11-debian-data-bases","status":"publish","type":"page","link":"https:\/\/itgen.itbumper.com\/?page_id=1226","title":{"rendered":"0053_MobaXterm macros: 11.Debian-Data Bases"},"content":{"rendered":"\r\n<p>11.1 Database Discovery. Detect installed database and data services.<br \/>11.2 Service Status. Verify systemd service state for detected database services.<br \/>11.3 Listening Ports. Identify active database network listeners.<br \/>11.4 Installed Versions. Display detected database software versions.<br \/>11.5 Database Processes. List running database-related processes and resource usage.<br \/>11.6 Configuration Files. Locate default configuration files and directories.<br \/>11.7 Storage Assessment. Analyze database storage usage, filesystem status, ownership, permissions, and mount options.<br \/>11.8 Log Assessment. Search system and native database logs for recent critical events.<br \/>11.9 PostgreSQL Assessment. Perform PostgreSQL-specific read-only diagnostics.<br \/>11.10 MySQL \/ MariaDB Assessment. Perform MySQL and MariaDB-specific read-only diagnostics.<br \/>11.11 Redis Assessment. Perform Redis-specific read-only diagnostics.<br \/>11.12 Replication &amp; High Availability Assessment. Search for replication, clustering, and high availability indicators.<br \/>11.13 Backup Assessment. Detect backup jobs, timers, backup files, and estimate backup freshness.<br \/>11.14 Database Health Summary. Present an overall health summary of the database environment.<\/p>\r\n\r\n\r\n\r\n<p><strong data-start=\"361\" data-end=\"376\">Why Base64?<\/strong><br data-start=\"376\" data-end=\"379\" \/>Base64 encoding allows complex multi-line Bash scripts to be safely delivered as a single command, avoiding issues with line breaks, quoting, and macro parsing while preserving the original script intact. Use: printf %s &lt;base64_data_ | base64 -d | bash<\/p>\r\n\r\n\r\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nprintf '%s' 'IyEvdXNyL2Jpbi9lbnYgYmFzaAoKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIyAxMS4gREFUQUJBU0UgJiBEQVRBIFNFUlZJQ0VTIEFTU0VTU01FTlQKIyBSZWFkLW9ubHkgZGlhZ25vc3RpY3MgZm9yIERlYmlhbiAvIFVidW50dSBzeXN0ZW1zCiMgTm8gcGFzc3dvcmRzIGFyZSByZXF1ZXN0ZWQgYW5kIG5vIGNvbmZpZ3VyYXRpb24gaXMgY2hhbmdlZC4KIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCnNldCAtdQpzZXQgLW8gcGlwZWZhaWwKCmlmIFsgLXQgMSBdICYmIFsgIiR7VEVSTTotZHVtYn0iICE9ICJkdW1iIiBdOyB0aGVuCiAgICBHUkVFTj0nXDAzM1swOzMybSc7IFJFRD0nXDAzM1swOzMxbSc7IFlFTExPVz0nXDAzM1sxOzMzbScKICAgIEJMVUU9J1wwMzNbMDszNG0nOyBDWUFOPSdcMDMzWzA7MzZtJzsgTkM9J1wwMzNbMG0nCmVsc2UKICAgIEdSRUVOPScnOyBSRUQ9Jyc7IFlFTExPVz0nJzsgQkxVRT0nJzsgQ1lBTj0nJzsgTkM9JycKZmkKCnByaW50X21haW5faGVhZGVyKCkgeyBwcmludGYgJyViXG5cbicgIiR7QkxVRX09PT09PT09PT09PT09PT09PT09PSAxMS4gREFUQUJBU0UgJiBEQVRBIFNFUlZJQ0VTID09PT09PT09PT09PT09PT09PT09JHtOQ30iOyB9CnByaW50X3NlY3Rpb24oKSB7IHByaW50ZiAnJWJcbicgIiR7QkxVRX0tLS0gJDEgLS0tJHtOQ30iOyB9CnByaW50X29rKCkgeyBwcmludGYgJyViXG4nICIke0dSRUVOfVtPS10ke05DfSAkMSI7IH0KcHJpbnRfaW5mbygpIHsgcHJpbnRmICclYlxuJyAiJHtDWUFOfVtJTkZPXSR7TkN9ICQxIjsgfQpwcmludF93YXJuaW5nKCkgeyBwcmludGYgJyViXG4nICIke1lFTExPV31bV0FSTklOR10ke05DfSAkMSI7IH0KcHJpbnRfY3JpdGljYWwoKSB7IHByaW50ZiAnJWJcbicgIiR7UkVEfVtDUklUSUNBTF0ke05DfSAkMSI7IH0KY29tbWFuZF9leGlzdHMoKSB7IGNvbW1hbmQgLXYgIiQxIiA+L2Rldi9udWxsIDI+JjE7IH0KCkZJTEVTWVNURU1fV0FSTklOR19USFJFU0hPTEQ9ODAKRklMRVNZU1RFTV9DUklUSUNBTF9USFJFU0hPTEQ9OTAKQkFDS1VQX1dBUk5JTkdfREFZUz03CkxPR19MT09LQkFDSz0nMjQgaG91cnMgYWdvJwoKZGVjbGFyZSAtQSBEQl9MQUJFTCBEQl9TRVJWSUNFIERCX0NPTU1BTkQgREJfUE9SVFMgREJfQ09ORklHIERCX0RBVEEgREJfTE9HUwpkZWNsYXJlIC1BIERCX0RFVEVDVEVEIERCX1NUQVRVUyBEQl9WRVJTSU9OCgpEQVRBQkFTRV9LRVlTPShwb3N0Z3Jlc3FsIG15c3FsIG1hcmlhZGIgbW9uZ29kYiByZWRpcyBlbGFzdGljc2VhcmNoIG9wZW5zZWFyY2ggY2xpY2tob3VzZSBpbmZsdXhkYiBjYXNzYW5kcmEgcmFiYml0bXEpCgpEQl9MQUJFTFtwb3N0Z3Jlc3FsXT0nUG9zdGdyZVNRTCc7IERCX1NFUlZJQ0VbcG9zdGdyZXNxbF09J3Bvc3RncmVzcWwnOyBEQl9DT01NQU5EW3Bvc3RncmVzcWxdPSdwc3FsJzsgREJfUE9SVFNbcG9zdGdyZXNxbF09JzU0MzInOyBEQl9DT05GSUdbcG9zdGdyZXNxbF09Jy9ldGMvcG9zdGdyZXNxbCc7IERCX0RBVEFbcG9zdGdyZXNxbF09Jy92YXIvbGliL3Bvc3RncmVzcWwnOyBEQl9MT0dTW3Bvc3RncmVzcWxdPScvdmFyL2xvZy9wb3N0Z3Jlc3FsJwpEQl9MQUJFTFtteXNxbF09J015U1FMJzsgREJfU0VSVklDRVtteXNxbF09J215c3FsJzsgREJfQ09NTUFORFtteXNxbF09J215c3FsJzsgREJfUE9SVFNbbXlzcWxdPSczMzA2JzsgREJfQ09ORklHW215c3FsXT0nL2V0Yy9teXNxbCc7IERCX0RBVEFbbXlzcWxdPScvdmFyL2xpYi9teXNxbCc7IERCX0xPR1NbbXlzcWxdPScvdmFyL2xvZy9teXNxbCcKREJfTEFCRUxbbWFyaWFkYl09J01hcmlhREInOyBEQl9TRVJWSUNFW21hcmlhZGJdPSdtYXJpYWRiJzsgREJfQ09NTUFORFttYXJpYWRiXT0nbWFyaWFkYic7IERCX1BPUlRTW21hcmlhZGJdPSczMzA2JzsgREJfQ09ORklHW21hcmlhZGJdPScvZXRjL215c3FsJzsgREJfREFUQVttYXJpYWRiXT0nL3Zhci9saWIvbXlzcWwnOyBEQl9MT0dTW21hcmlhZGJdPScvdmFyL2xvZy9teXNxbCcKREJfTEFCRUxbbW9uZ29kYl09J01vbmdvREInOyBEQl9TRVJWSUNFW21vbmdvZGJdPSdtb25nb2QnOyBEQl9DT01NQU5EW21vbmdvZGJdPSdtb25nb3NoJzsgREJfUE9SVFNbbW9uZ29kYl09JzI3MDE3JzsgREJfQ09ORklHW21vbmdvZGJdPScvZXRjL21vbmdvZC5jb25mJzsgREJfREFUQVttb25nb2RiXT0nL3Zhci9saWIvbW9uZ29kYic7IERCX0xPR1NbbW9uZ29kYl09Jy92YXIvbG9nL21vbmdvZGInCkRCX0xBQkVMW3JlZGlzXT0nUmVkaXMnOyBEQl9TRVJWSUNFW3JlZGlzXT0ncmVkaXMtc2VydmVyJzsgREJfQ09NTUFORFtyZWRpc109J3JlZGlzLWNsaSc7IERCX1BPUlRTW3JlZGlzXT0nNjM3OSc7IERCX0NPTkZJR1tyZWRpc109Jy9ldGMvcmVkaXMnOyBEQl9EQVRBW3JlZGlzXT0nL3Zhci9saWIvcmVkaXMnOyBEQl9MT0dTW3JlZGlzXT0nL3Zhci9sb2cvcmVkaXMnCkRCX0xBQkVMW2VsYXN0aWNzZWFyY2hdPSdFbGFzdGljc2VhcmNoJzsgREJfU0VSVklDRVtlbGFzdGljc2VhcmNoXT0nZWxhc3RpY3NlYXJjaCc7IERCX0NPTU1BTkRbZWxhc3RpY3NlYXJjaF09J2VsYXN0aWNzZWFyY2gnOyBEQl9QT1JUU1tlbGFzdGljc2VhcmNoXT0nOTIwMCA5MzAwJzsgREJfQ09ORklHW2VsYXN0aWNzZWFyY2hdPScvZXRjL2VsYXN0aWNzZWFyY2gnOyBEQl9EQVRBW2VsYXN0aWNzZWFyY2hdPScvdmFyL2xpYi9lbGFzdGljc2VhcmNoJzsgREJfTE9HU1tlbGFzdGljc2VhcmNoXT0nL3Zhci9sb2cvZWxhc3RpY3NlYXJjaCcKREJfTEFCRUxbb3BlbnNlYXJjaF09J09wZW5TZWFyY2gnOyBEQl9TRVJWSUNFW29wZW5zZWFyY2hdPSdvcGVuc2VhcmNoJzsgREJfQ09NTUFORFtvcGVuc2VhcmNoXT0nb3BlbnNlYXJjaCc7IERCX1BPUlRTW29wZW5zZWFyY2hdPSc5MjAwIDkzMDAnOyBEQl9DT05GSUdbb3BlbnNlYXJjaF09Jy9ldGMvb3BlbnNlYXJjaCc7IERCX0RBVEFbb3BlbnNlYXJjaF09Jy92YXIvbGliL29wZW5zZWFyY2gnOyBEQl9MT0dTW29wZW5zZWFyY2hdPScvdmFyL2xvZy9vcGVuc2VhcmNoJwpEQl9MQUJFTFtjbGlja2hvdXNlXT0nQ2xpY2tIb3VzZSc7IERCX1NFUlZJQ0VbY2xpY2tob3VzZV09J2NsaWNraG91c2Utc2VydmVyJzsgREJfQ09NTUFORFtjbGlja2hvdXNlXT0nY2xpY2tob3VzZS1jbGllbnQnOyBEQl9QT1JUU1tjbGlja2hvdXNlXT0nODEyMyA5MDAwJzsgREJfQ09ORklHW2NsaWNraG91c2VdPScvZXRjL2NsaWNraG91c2Utc2VydmVyJzsgREJfREFUQVtjbGlja2hvdXNlXT0nL3Zhci9saWIvY2xpY2tob3VzZSc7IERCX0xPR1NbY2xpY2tob3VzZV09Jy92YXIvbG9nL2NsaWNraG91c2Utc2VydmVyJwpEQl9MQUJFTFtpbmZsdXhkYl09J0luZmx1eERCJzsgREJfU0VSVklDRVtpbmZsdXhkYl09J2luZmx1eGRiJzsgREJfQ09NTUFORFtpbmZsdXhkYl09J2luZmx1eCc7IERCX1BPUlRTW2luZmx1eGRiXT0nODA4Nic7IERCX0NPTkZJR1tpbmZsdXhkYl09Jy9ldGMvaW5mbHV4ZGInOyBEQl9EQVRBW2luZmx1eGRiXT0nL3Zhci9saWIvaW5mbHV4ZGInOyBEQl9MT0dTW2luZmx1eGRiXT0nL3Zhci9sb2cvaW5mbHV4ZGInCkRCX0xBQkVMW2Nhc3NhbmRyYV09J0Nhc3NhbmRyYSc7IERCX1NFUlZJQ0VbY2Fzc2FuZHJhXT0nY2Fzc2FuZHJhJzsgREJfQ09NTUFORFtjYXNzYW5kcmFdPSdjcWxzaCc7IERCX1BPUlRTW2Nhc3NhbmRyYV09JzkwNDInOyBEQl9DT05GSUdbY2Fzc2FuZHJhXT0nL2V0Yy9jYXNzYW5kcmEnOyBEQl9EQVRBW2Nhc3NhbmRyYV09Jy92YXIvbGliL2Nhc3NhbmRyYSc7IERCX0xPR1NbY2Fzc2FuZHJhXT0nL3Zhci9sb2cvY2Fzc2FuZHJhJwpEQl9MQUJFTFtyYWJiaXRtcV09J1JhYmJpdE1RJzsgREJfU0VSVklDRVtyYWJiaXRtcV09J3JhYmJpdG1xLXNlcnZlcic7IERCX0NPTU1BTkRbcmFiYml0bXFdPSdyYWJiaXRtcWN0bCc7IERCX1BPUlRTW3JhYmJpdG1xXT0nNTY3MiAxNTY3Mic7IERCX0NPTkZJR1tyYWJiaXRtcV09Jy9ldGMvcmFiYml0bXEnOyBEQl9EQVRBW3JhYmJpdG1xXT0nL3Zhci9saWIvcmFiYml0bXEnOyBEQl9MT0dTW3JhYmJpdG1xXT0nL3Zhci9sb2cvcmFiYml0bXEnCgpERVRFQ1RFRF9DT1VOVD0wCkxJU1RFTklOR19QT1JUX0NPVU5UPTAKRkFJTEVEX1NFUlZJQ0VfQ09VTlQ9MApMT0dfV0FSTklOR19DT1VOVD0wClNUT1JBR0VfV0FSTklOR19DT1VOVD0wClNUT1JBR0VfQ1JJVElDQUxfQ09VTlQ9MApCQUNLVVBfU1RBVFVTPSdOT1QgRk9VTkQnCk5FV0VTVF9CQUNLVVA9J04vQScKCnNlcnZpY2VfdW5pdF9leGlzdHMoKSB7CiAgICBsb2NhbCBzZXJ2aWNlPSIkMSIKICAgIHN5c3RlbWN0bCBsaXN0LXVuaXQtZmlsZXMgLS10eXBlPXNlcnZpY2UgLS1uby1sZWdlbmQgMj4vZGV2L251bGwgfCBhd2sgJ3twcmludCAkMX0nIHwgZ3JlcCAtRnhxICIke3NlcnZpY2V9LnNlcnZpY2UiCn0KCnBhY2thZ2VfaW5zdGFsbGVkX21hdGNoaW5nKCkgewogICAgbG9jYWwgcGF0dGVybj0iJDEiCiAgICBjb21tYW5kX2V4aXN0cyBkcGtnLXF1ZXJ5IHx8IHJldHVybiAxCiAgICBkcGtnLXF1ZXJ5IC1XIC1mPScke1BhY2thZ2V9XG4nIDI+L2Rldi9udWxsIHwgZ3JlcCAtRWlxICIkcGF0dGVybiIKfQoKZGV0ZWN0X2RhdGFiYXNlKCkgewogICAgbG9jYWwga2V5PSIkMSIgc2VydmljZT0iJHtEQl9TRVJWSUNFWyQxXX0iIGNtZD0iJHtEQl9DT01NQU5EWyQxXX0iIGNvbmZpZz0iJHtEQl9DT05GSUdbJDFdfSIgZGF0YT0iJHtEQl9EQVRBWyQxXX0iIGRldGVjdGVkPTAKICAgIHNlcnZpY2VfdW5pdF9leGlzdHMgIiRzZXJ2aWNlIiAmJiBkZXRlY3RlZD0xCiAgICBjb21tYW5kX2V4aXN0cyAiJGNtZCIgJiYgZGV0ZWN0ZWQ9MQogICAgeyBbIC1lICIkY29uZmlnIiBdIHx8IFsgLWQgIiRkYXRhIiBdOyB9ICYmIGRldGVjdGVkPTEKICAgIGNhc2UgIiRrZXkiIGluCiAgICAgICAgcG9zdGdyZXNxbCkgcGFja2FnZV9pbnN0YWxsZWRfbWF0Y2hpbmcgJ15wb3N0Z3Jlc3FsKFswLTkuLV18JCl8XnBvc3RncmVzcWwtJyAmJiBkZXRlY3RlZD0xIDs7CiAgICAgICAgbXlzcWwpIHBhY2thZ2VfaW5zdGFsbGVkX21hdGNoaW5nICdebXlzcWwtc2VydmVyfF5teXNxbC1jbGllbnQnICYmIGRldGVjdGVkPTEgOzsKICAgICAgICBtYXJpYWRiKSBwYWNrYWdlX2luc3RhbGxlZF9tYXRjaGluZyAnXm1hcmlhZGItc2VydmVyfF5tYXJpYWRiLWNsaWVudCcgJiYgZGV0ZWN0ZWQ9MSA7OwogICAgICAgIG1vbmdvZGIpIHBhY2thZ2VfaW5zdGFsbGVkX21hdGNoaW5nICdebW9uZ29kYnxebW9uZ29kYi1vcmcnICYmIGRldGVjdGVkPTEgOzsKICAgICAgICByZWRpcykgcGFja2FnZV9pbnN0YWxsZWRfbWF0Y2hpbmcgJ15yZWRpcy1zZXJ2ZXJ8XnJlZGlzLXRvb2xzJyAmJiBkZXRlY3RlZD0xIDs7CiAgICAgICAgZWxhc3RpY3NlYXJjaCkgcGFja2FnZV9pbnN0YWxsZWRfbWF0Y2hpbmcgJ15lbGFzdGljc2VhcmNoJCcgJiYgZGV0ZWN0ZWQ9MSA7OwogICAgICAgIG9wZW5zZWFyY2gpIHBhY2thZ2VfaW5zdGFsbGVkX21hdGNoaW5nICdeb3BlbnNlYXJjaCcgJiYgZGV0ZWN0ZWQ9MSA7OwogICAgICAgIGNsaWNraG91c2UpIHBhY2thZ2VfaW5zdGFsbGVkX21hdGNoaW5nICdeY2xpY2tob3VzZS0nICYmIGRldGVjdGVkPTEgOzsKICAgICAgICBpbmZsdXhkYikgcGFja2FnZV9pbnN0YWxsZWRfbWF0Y2hpbmcgJ15pbmZsdXhkYicgJiYgZGV0ZWN0ZWQ9MSA7OwogICAgICAgIGNhc3NhbmRyYSkgcGFja2FnZV9pbnN0YWxsZWRfbWF0Y2hpbmcgJ15jYXNzYW5kcmEkJyAmJiBkZXRlY3RlZD0xIDs7CiAgICAgICAgcmFiYml0bXEpIHBhY2thZ2VfaW5zdGFsbGVkX21hdGNoaW5nICdecmFiYml0bXEtc2VydmVyJCcgJiYgZGV0ZWN0ZWQ9MSA7OwogICAgZXNhYwogICAgREJfREVURUNURURbJGtleV09IiRkZXRlY3RlZCIKfQoKZ2V0X3NlcnZpY2Vfc3RhdGUoKSB7CiAgICBsb2NhbCBzZXJ2aWNlPSIkMSIgc3RhdGUKICAgIHNlcnZpY2VfdW5pdF9leGlzdHMgIiRzZXJ2aWNlIiB8fCB7IHByaW50ZiAnTk8gVU5JVCc7IHJldHVybjsgfQogICAgc3RhdGU9JChzeXN0ZW1jdGwgaXMtYWN0aXZlICIkc2VydmljZSIgMj4vZGV2L251bGwgfHwgdHJ1ZSkKICAgIGNhc2UgIiRzdGF0ZSIgaW4KICAgICAgICBhY3RpdmUpIHByaW50ZiAnUlVOTklORycgOzsKICAgICAgICBpbmFjdGl2ZSkgcHJpbnRmICdTVE9QUEVEJyA7OwogICAgICAgIGZhaWxlZCkgcHJpbnRmICdGQUlMRUQnIDs7CiAgICAgICAgYWN0aXZhdGluZykgcHJpbnRmICdTVEFSVElORycgOzsKICAgICAgICBkZWFjdGl2YXRpbmcpIHByaW50ZiAnU1RPUFBJTkcnIDs7CiAgICAgICAgKikgcHJpbnRmICclcycgIiR7c3RhdGVeXn0iIDs7CiAgICBlc2FjCn0KCmdldF92ZXJzaW9uKCkgewogICAgbG9jYWwga2V5PSIkMSIgb3V0cHV0PScnCiAgICBjYXNlICIka2V5IiBpbgogICAgICAgIHBvc3RncmVzcWwpIGNvbW1hbmRfZXhpc3RzIHBzcWwgJiYgb3V0cHV0PSQocHNxbCAtLXZlcnNpb24gMj4mMSB8IGhlYWQgLW4gMSkgOzsKICAgICAgICBteXNxbCkgY29tbWFuZF9leGlzdHMgbXlzcWwgJiYgb3V0cHV0PSQobXlzcWwgLS12ZXJzaW9uIDI+JjEgfCBoZWFkIC1uIDEpIDs7CiAgICAgICAgbWFyaWFkYikgY29tbWFuZF9leGlzdHMgbWFyaWFkYiAmJiBvdXRwdXQ9JChtYXJpYWRiIC0tdmVyc2lvbiAyPiYxIHwgaGVhZCAtbiAxKSA7OwogICAgICAgIG1vbmdvZGIpIGlmIGNvbW1hbmRfZXhpc3RzIG1vbmdvc2g7IHRoZW4gb3V0cHV0PSQobW9uZ29zaCAtLXZlcnNpb24gMj4mMSB8IGhlYWQgLW4gMSk7IGVsaWYgY29tbWFuZF9leGlzdHMgbW9uZ29kOyB0aGVuIG91dHB1dD0kKG1vbmdvZCAtLXZlcnNpb24gMj4mMSB8IGhlYWQgLW4gMSk7IGZpIDs7CiAgICAgICAgcmVkaXMpIGNvbW1hbmRfZXhpc3RzIHJlZGlzLXNlcnZlciAmJiBvdXRwdXQ9JChyZWRpcy1zZXJ2ZXIgLS12ZXJzaW9uIDI+JjEgfCBoZWFkIC1uIDEpIDs7CiAgICAgICAgZWxhc3RpY3NlYXJjaCkgaWYgY29tbWFuZF9leGlzdHMgZWxhc3RpY3NlYXJjaDsgdGhlbiBvdXRwdXQ9JChlbGFzdGljc2VhcmNoIC0tdmVyc2lvbiAyPiYxIHwgaGVhZCAtbiAxKTsgZWxpZiBbIC14IC91c3Ivc2hhcmUvZWxhc3RpY3NlYXJjaC9iaW4vZWxhc3RpY3NlYXJjaCBdOyB0aGVuIG91dHB1dD0kKC91c3Ivc2hhcmUvZWxhc3RpY3NlYXJjaC9iaW4vZWxhc3RpY3NlYXJjaCAtLXZlcnNpb24gMj4mMSB8IGhlYWQgLW4gMSk7IGZpIDs7CiAgICAgICAgb3BlbnNlYXJjaCkgaWYgY29tbWFuZF9leGlzdHMgb3BlbnNlYXJjaDsgdGhlbiBvdXRwdXQ9JChvcGVuc2VhcmNoIC0tdmVyc2lvbiAyPiYxIHwgaGVhZCAtbiAxKTsgZWxpZiBbIC14IC91c3Ivc2hhcmUvb3BlbnNlYXJjaC9iaW4vb3BlbnNlYXJjaCBdOyB0aGVuIG91dHB1dD0kKC91c3Ivc2hhcmUvb3BlbnNlYXJjaC9iaW4vb3BlbnNlYXJjaCAtLXZlcnNpb24gMj4mMSB8IGhlYWQgLW4gMSk7IGZpIDs7CiAgICAgICAgY2xpY2tob3VzZSkgY29tbWFuZF9leGlzdHMgY2xpY2tob3VzZS1jbGllbnQgJiYgb3V0cHV0PSQoY2xpY2tob3VzZS1jbGllbnQgLS12ZXJzaW9uIDI+JjEgfCBoZWFkIC1uIDEpIDs7CiAgICAgICAgaW5mbHV4ZGIpIGNvbW1hbmRfZXhpc3RzIGluZmx1eCAmJiBvdXRwdXQ9JChpbmZsdXggdmVyc2lvbiAyPiYxIHwgaGVhZCAtbiAxKSA7OwogICAgICAgIGNhc3NhbmRyYSkgY29tbWFuZF9leGlzdHMgY2Fzc2FuZHJhICYmIG91dHB1dD0kKGNhc3NhbmRyYSAtdiAyPiYxIHwgaGVhZCAtbiAxKSA7OwogICAgICAgIHJhYmJpdG1xKSBjb21tYW5kX2V4aXN0cyByYWJiaXRtcWN0bCAmJiBvdXRwdXQ9JChyYWJiaXRtcWN0bCB2ZXJzaW9uIDI+L2Rldi9udWxsIHwgaGVhZCAtbiAxKSA7OwogICAgZXNhYwogICAgWyAtbiAiJG91dHB1dCIgXSAmJiBwcmludGYgJyVzJyAiJG91dHB1dCIgfHwgcHJpbnRmICdVTktOT1dOJwp9CgpwcmludF9tYWluX2hlYWRlcgoKcHJpbnRfc2VjdGlvbiAnMTEuMSBEQVRBQkFTRSBESVNDT1ZFUlknCmZvciBrZXkgaW4gIiR7REFUQUJBU0VfS0VZU1tAXX0iOyBkbwogICAgZGV0ZWN0X2RhdGFiYXNlICIka2V5IgogICAgaWYgWyAiJHtEQl9ERVRFQ1RFRFska2V5XX0iIC1lcSAxIF07IHRoZW4KICAgICAgICBERVRFQ1RFRF9DT1VOVD0kKChERVRFQ1RFRF9DT1VOVCArIDEpKQogICAgICAgIERCX1ZFUlNJT05bJGtleV09IiQoZ2V0X3ZlcnNpb24gIiRrZXkiKSIKICAgICAgICBwcmludGYgJyAgJS0xOHMgJWJERVRFQ1RFRCViXG4nICIke0RCX0xBQkVMWyRrZXldfSIgIiRHUkVFTiIgIiROQyIKICAgICAgICBwcmludGYgJyAgICBWZXJzaW9uOiAlc1xuJyAiJHtEQl9WRVJTSU9OWyRrZXldfSIKICAgIGVsc2UKICAgICAgICBEQl9WRVJTSU9OWyRrZXldPSdOL0EnCiAgICAgICAgcHJpbnRmICcgICUtMThzIE5PVCBERVRFQ1RFRFxuJyAiJHtEQl9MQUJFTFska2V5XX0iCiAgICBmaQpkb25lClsgIiRERVRFQ1RFRF9DT1VOVCIgLWVxIDAgXSAmJiBwcmludF9pbmZvICdObyBzdXBwb3J0ZWQgZGF0YWJhc2Ugb3IgZGF0YSBzZXJ2aWNlIHdhcyBkZXRlY3RlZC4nIHx8IHByaW50X29rICIkREVURUNURURfQ09VTlQgc3VwcG9ydGVkIGRhdGFiYXNlIG9yIGRhdGEgc2VydmljZShzKSBkZXRlY3RlZC4iCnByaW50ZiAnXG4nCgpwcmludF9zZWN0aW9uICcxMS4yIFNFUlZJQ0UgU1RBVFVTJwpmb3Iga2V5IGluICIke0RBVEFCQVNFX0tFWVNbQF19IjsgZG8KICAgIGlmIFsgIiR7REJfREVURUNURURbJGtleV19IiAtbmUgMSBdOyB0aGVuIERCX1NUQVRVU1ska2V5XT0nTk9UIElOU1RBTExFRCc7IGNvbnRpbnVlOyBmaQogICAgREJfU1RBVFVTWyRrZXldPSIkKGdldF9zZXJ2aWNlX3N0YXRlICIke0RCX1NFUlZJQ0VbJGtleV19IikiCiAgICBjYXNlICIke0RCX1NUQVRVU1ska2V5XX0iIGluCiAgICAgICAgUlVOTklORykgcHJpbnRmICcgICUtMThzICViUlVOTklORyViXG4nICIke0RCX0xBQkVMWyRrZXldfSIgIiRHUkVFTiIgIiROQyIgOzsKICAgICAgICBGQUlMRUQpIHByaW50ZiAnICAlLTE4cyAlYkZBSUxFRCViXG4nICIke0RCX0xBQkVMWyRrZXldfSIgIiRSRUQiICIkTkMiOyBGQUlMRURfU0VSVklDRV9DT1VOVD0kKChGQUlMRURfU0VSVklDRV9DT1VOVCArIDEpKSA7OwogICAgICAgIFNUT1BQRUR8J05PIFVOSVQnKSBwcmludGYgJyAgJS0xOHMgJWIlcyViXG4nICIke0RCX0xBQkVMWyRrZXldfSIgIiRZRUxMT1ciICIke0RCX1NUQVRVU1ska2V5XX0iICIkTkMiIDs7CiAgICAgICAgKikgcHJpbnRmICcgICUtMThzICVzXG4nICIke0RCX0xBQkVMWyRrZXldfSIgIiR7REJfU1RBVFVTWyRrZXldfSIgOzsKICAgIGVzYWMKZG9uZQpbICIkRkFJTEVEX1NFUlZJQ0VfQ09VTlQiIC1ndCAwIF0gJiYgcHJpbnRfY3JpdGljYWwgIiRGQUlMRURfU0VSVklDRV9DT1VOVCBkYXRhYmFzZSBzZXJ2aWNlKHMpIGFyZSBpbiBmYWlsZWQgc3RhdGUuIgpwcmludGYgJ1xuJwoKcHJpbnRfc2VjdGlvbiAnMTEuMyBMSVNURU5JTkcgUE9SVFMnCmlmICEgY29tbWFuZF9leGlzdHMgc3M7IHRoZW4KICAgIHByaW50X3dhcm5pbmcgJ1RoZSBzcyBjb21tYW5kIGlzIHVuYXZhaWxhYmxlLicKZWxzZQogICAgZm9yIGtleSBpbiAiJHtEQVRBQkFTRV9LRVlTW0BdfSI7IGRvCiAgICAgICAgWyAiJHtEQl9ERVRFQ1RFRFska2V5XX0iIC1lcSAxIF0gfHwgY29udGludWUKICAgICAgICBmb3IgcG9ydCBpbiAke0RCX1BPUlRTWyRrZXldfTsgZG8KICAgICAgICAgICAgcG9ydF9vdXRwdXQ9JChzcyAtbG50dXAgMj4vZGV2L251bGwgfCBhd2sgLXYgcG9ydD0iOiRwb3J0IiAnJDUgfiBwb3J0IiQiIHx8ICQ1IH4gcG9ydCJbXjAtOV0iJykKICAgICAgICAgICAgaWYgWyAtbiAiJHBvcnRfb3V0cHV0IiBdOyB0aGVuCiAgICAgICAgICAgICAgICBMSVNURU5JTkdfUE9SVF9DT1VOVD0kKChMSVNURU5JTkdfUE9SVF9DT1VOVCArIDEpKQogICAgICAgICAgICAgICAgcHJpbnRmICcgICViJXMlYiAoJXMpXG4nICIkR1JFRU4iICIkcG9ydCIgIiROQyIgIiR7REJfTEFCRUxbJGtleV19IgogICAgICAgICAgICAgICAgcHJpbnRmICclc1xuJyAiJHBvcnRfb3V0cHV0IiB8IHNlZCAncy9eLyAgICAvJwogICAgICAgICAgICBmaQogICAgICAgIGRvbmUKICAgIGRvbmUKICAgIFsgIiRMSVNURU5JTkdfUE9SVF9DT1VOVCIgLWVxIDAgXSAmJiBwcmludF9pbmZvICdObyBrbm93biBkYXRhYmFzZSBsaXN0ZW5pbmcgcG9ydHMgd2VyZSBkZXRlY3RlZC4nCmZpCnByaW50ZiAnXG4nCgpwcmludF9zZWN0aW9uICcxMS40IElOU1RBTExFRCBWRVJTSU9OUycKZm9yIGtleSBpbiAiJHtEQVRBQkFTRV9LRVlTW0BdfSI7IGRvIFsgIiR7REJfREVURUNURURbJGtleV19IiAtZXEgMSBdICYmIHByaW50ZiAnICAlLTE4cyAlc1xuJyAiJHtEQl9MQUJFTFska2V5XX0iICIke0RCX1ZFUlNJT05bJGtleV19IjsgZG9uZQpbICIkREVURUNURURfQ09VTlQiIC1lcSAwIF0gJiYgcHJpbnRfaW5mbyAnTm90aGluZyB0byByZXBvcnQuJwpwcmludGYgJ1xuJwoKcHJpbnRfc2VjdGlvbiAnMTEuNSBEQVRBQkFTRSBQUk9DRVNTRVMnClBST0NFU1NfUEFUVEVSTj0ncG9zdGdyZXN8cG9zdG1hc3RlcnxteXNxbGR8bWFyaWFkYmR8bW9uZ29kfHJlZGlzLXNlcnZlcnxlbGFzdGljc2VhcmNofG9wZW5zZWFyY2h8Y2xpY2tob3VzZS1zZXJ2ZXJ8aW5mbHV4ZHxjYXNzYW5kcmF8YmVhbS5zbXAnCnByb2Nlc3Nfb3V0cHV0PSQocHMgLWVvIHBpZCxwcGlkLHVzZXIsJWNwdSwlbWVtLGV0aW1lLGNvbW0sYXJncyAtLXNvcnQ9LSVjcHUgMj4vZGV2L251bGwgfCBncmVwIC1FaSAiJFBST0NFU1NfUEFUVEVSTiIgfCBncmVwIC1FdiAnZ3JlcCAtRXxkYXRhYmFzZV9hc3Nlc3NtZW50JyB8IGhlYWQgLW4gMjUgfHwgdHJ1ZSkKWyAtbiAiJHByb2Nlc3Nfb3V0cHV0IiBdICYmIHByaW50ZiAnJXNcbicgIiRwcm9jZXNzX291dHB1dCIgfHwgcHJpbnRfaW5mbyAnTm8gbWF0Y2hpbmcgZGF0YWJhc2UgcHJvY2Vzc2VzIHdlcmUgZm91bmQuJwpwcmludGYgJ1xuJwoKcHJpbnRfc2VjdGlvbiAnMTEuNiBDT05GSUdVUkFUSU9OIEZJTEVTJwpmb3Iga2V5IGluICIke0RBVEFCQVNFX0tFWVNbQF19IjsgZG8KICAgIFsgIiR7REJfREVURUNURURbJGtleV19IiAtZXEgMSBdIHx8IGNvbnRpbnVlCiAgICBjb25maWc9IiR7REJfQ09ORklHWyRrZXldfSIKICAgIFsgLWUgIiRjb25maWciIF0gJiYgcHJpbnRmICcgICUtMThzICVzXG4nICIke0RCX0xBQkVMWyRrZXldfSIgIiRjb25maWciIHx8IHByaW50ZiAnICAlLTE4cyBOT1QgRk9VTkQgQVQgREVGQVVMVCBQQVRIXG4nICIke0RCX0xBQkVMWyRrZXldfSIKZG9uZQpwcmludF9pbmZvICdDb25maWd1cmF0aW9uIGNvbnRlbnRzIGFyZSBub3QgZGlzcGxheWVkIHRvIGF2b2lkIGV4cG9zaW5nIGNyZWRlbnRpYWxzIG9yIHNlY3JldHMuJwpwcmludGYgJ1xuJwoKcHJpbnRfc2VjdGlvbiAnMTEuNyBTVE9SQUdFIEFTU0VTU01FTlQnCmZvciBrZXkgaW4gIiR7REFUQUJBU0VfS0VZU1tAXX0iOyBkbwogICAgWyAiJHtEQl9ERVRFQ1RFRFska2V5XX0iIC1lcSAxIF0gfHwgY29udGludWUKICAgIGRhdGFfZGlyPSIke0RCX0RBVEFbJGtleV19IjsgWyAtZCAiJGRhdGFfZGlyIiBdIHx8IGNvbnRpbnVlCiAgICBzaXplPSQoZHUgLXNoeCAiJGRhdGFfZGlyIiAyPi9kZXYvbnVsbCB8IGF3ayAne3ByaW50ICQxfScpOyBbIC1uICIkc2l6ZSIgXSB8fCBzaXplPSdQRVJNSVNTSU9OIERFTklFRCcKICAgIGZzX2xpbmU9JChkZiAtUFRoICIkZGF0YV9kaXIiIDI+L2Rldi9udWxsIHwgdGFpbCAtbiAxKQogICAgZmlsZXN5c3RlbT0kKHByaW50ZiAnJXNcbicgIiRmc19saW5lIiB8IGF3ayAne3ByaW50ICQxfScpOyBmc190eXBlPSQocHJpbnRmICclc1xuJyAiJGZzX2xpbmUiIHwgYXdrICd7cHJpbnQgJDJ9JykKICAgIGF2YWlsYWJsZT0kKHByaW50ZiAnJXNcbicgIiRmc19saW5lIiB8IGF3ayAne3ByaW50ICQ1fScpOyB1c2VfcGN0PSQocHJpbnRmICclc1xuJyAiJGZzX2xpbmUiIHwgYXdrICd7Z3N1YigiJSIsIiIsJDYpOyBwcmludCAkNn0nKQogICAgbW91bnRwb2ludD0kKHByaW50ZiAnJXNcbicgIiRmc19saW5lIiB8IGF3ayAne3ByaW50ICQ3fScpCiAgICBvd25lcj0kKHN0YXQgLWMgJyVVOiVHJyAiJGRhdGFfZGlyIiAyPi9kZXYvbnVsbCB8fCBwcmludGYgJ1VOS05PV04nKQogICAgcGVybWlzc2lvbnM9JChzdGF0IC1jICclQSAoJWEpJyAiJGRhdGFfZGlyIiAyPi9kZXYvbnVsbCB8fCBwcmludGYgJ1VOS05PV04nKQogICAgbW91bnRfb3B0aW9ucz0kKGZpbmRtbnQgLW5vIE9QVElPTlMgLVQgIiRkYXRhX2RpciIgMj4vZGV2L251bGwgfHwgcHJpbnRmICdVTktOT1dOJykKICAgIHByaW50ZiAnICAlc1xuJyAiJHtEQl9MQUJFTFska2V5XX0iCiAgICBwcmludGYgJyAgICBEYXRhIGRpcmVjdG9yeSA6ICVzXG4gICAgRGlyZWN0b3J5IHNpemUgOiAlc1xuICAgIE93bmVyICAgICAgICAgICA6ICVzXG4gICAgUGVybWlzc2lvbnMgICAgIDogJXNcbicgIiRkYXRhX2RpciIgIiRzaXplIiAiJG93bmVyIiAiJHBlcm1pc3Npb25zIgogICAgcHJpbnRmICcgICAgRmlsZXN5c3RlbSAgICAgIDogJXMgKCVzKVxuICAgIE1vdW50IHBvaW50ICAgICA6ICVzXG4gICAgQXZhaWxhYmxlICAgICAgIDogJXNcbiAgICBVc2VkICAgICAgICAgICAgOiAlcyUlXG4gICAgTW91bnQgb3B0aW9ucyAgIDogJXNcbicgIiR7ZmlsZXN5c3RlbTotVU5LTk9XTn0iICIke2ZzX3R5cGU6LVVOS05PV059IiAiJHttb3VudHBvaW50Oi1VTktOT1dOfSIgIiR7YXZhaWxhYmxlOi1VTktOT1dOfSIgIiR7dXNlX3BjdDotVU5LTk9XTn0iICIkbW91bnRfb3B0aW9ucyIKICAgIGlmIFtbICIke3VzZV9wY3Q6LX0iID1+IF5bMC05XSskIF1dOyB0aGVuCiAgICAgICAgaWYgWyAiJHVzZV9wY3QiIC1nZSAiJEZJTEVTWVNURU1fQ1JJVElDQUxfVEhSRVNIT0xEIiBdOyB0aGVuIHByaW50X2NyaXRpY2FsICIke0RCX0xBQkVMWyRrZXldfSBzdG9yYWdlIGlzICR7dXNlX3BjdH0lIHVzZWQuIjsgU1RPUkFHRV9DUklUSUNBTF9DT1VOVD0kKChTVE9SQUdFX0NSSVRJQ0FMX0NPVU5UICsgMSkpCiAgICAgICAgZWxpZiBbICIkdXNlX3BjdCIgLWdlICIkRklMRVNZU1RFTV9XQVJOSU5HX1RIUkVTSE9MRCIgXTsgdGhlbiBwcmludF93YXJuaW5nICIke0RCX0xBQkVMWyRrZXldfSBzdG9yYWdlIGlzICR7dXNlX3BjdH0lIHVzZWQuIjsgU1RPUkFHRV9XQVJOSU5HX0NPVU5UPSQoKFNUT1JBR0VfV0FSTklOR19DT1VOVCArIDEpKQogICAgICAgIGVsc2UgcHJpbnRfb2sgIiR7REJfTEFCRUxbJGtleV19IHN0b3JhZ2UgdXRpbGl6YXRpb24gaXMgd2l0aGluIHRocmVzaG9sZC4iOyBmaQogICAgZmkKICAgIGNhc2UgIiwkbW91bnRfb3B0aW9ucywiIGluICoscm8sKikgcHJpbnRfY3JpdGljYWwgIiRkYXRhX2RpciBpcyBtb3VudGVkIHJlYWQtb25seS4iOyBTVE9SQUdFX0NSSVRJQ0FMX0NPVU5UPSQoKFNUT1JBR0VfQ1JJVElDQUxfQ09VTlQgKyAxKSkgOzsgZXNhYwogICAgcHJpbnRmICdcbicKZG9uZQppZiBbIC1kIC92YXIvbGliL3Bvc3RncmVzcWwgXTsgdGhlbgogICAgd2hpbGUgSUZTPSByZWFkIC1yIHdhbF9kaXI7IGRvIFsgLW4gIiR3YWxfZGlyIiBdIHx8IGNvbnRpbnVlOyB3YWxfc2l6ZT0kKGR1IC1zaHggIiR3YWxfZGlyIiAyPi9kZXYvbnVsbCB8IGF3ayAne3ByaW50ICQxfScpOyBwcmludGYgJyAgUG9zdGdyZVNRTCBXQUw6ICVzICglcylcbicgIiR3YWxfZGlyIiAiJHt3YWxfc2l6ZTotVU5LTk9XTn0iOyBkb25lIDwgPChmaW5kIC92YXIvbGliL3Bvc3RncmVzcWwgLXR5cGUgZCAtbmFtZSBwZ193YWwgLXByaW50IDI+L2Rldi9udWxsIHwgaGVhZCAtbiAxMCkKZmkKaWYgWyAtZCAvdmFyL2xpYi9teXNxbCBdOyB0aGVuCiAgICBiaW5sb2dfc3VtbWFyeT0kKGZpbmQgL3Zhci9saWIvbXlzcWwgLW1heGRlcHRoIDEgLXR5cGUgZiBcKCAtbmFtZSAnbXlzcWwtYmluLionIC1vIC1uYW1lICdtYXJpYWRiLWJpbi4qJyAtbyAtbmFtZSAnYmlubG9nLionIFwpIC1wcmludGYgJyVzXG4nIDI+L2Rldi9udWxsIHwgYXdrICd7c3VtKz0kMTsgY291bnQrK30gRU5EIHtpZiAoY291bnQ+MCkgcHJpbnRmICIlZCBmaWxlKHMpLCAlLjJmIEdpQiIsIGNvdW50LCBzdW0vMTAyNC8xMDI0LzEwMjR9JykKICAgIFsgLW4gIiRiaW5sb2dfc3VtbWFyeSIgXSAmJiBwcmludGYgJyAgTXlTUUwvTWFyaWFEQiBiaW5sb2dzOiAlc1xuJyAiJGJpbmxvZ19zdW1tYXJ5IgpmaQpwcmludGYgJ1xuJwoKcHJpbnRfc2VjdGlvbiAnMTEuOCBMT0cgQVNTRVNTTUVOVCcKRVJST1JfUEFUVEVSTj0ncGFuaWN8ZmF0YWx8Y29ycnVwdHxjb3JydXB0aW9ufG91dCBvZiBtZW1vcnl8b29tfGtpbGxlZCBwcm9jZXNzfGRpc2sgZnVsbHxubyBzcGFjZSBsZWZ0fHJlYWQtb25seSBmaWxlIHN5c3RlbXx0b28gbWFueSBjb25uZWN0aW9uc3xyZXBsaWNhdGlvbi4qZXJyb3J8d2FsLiplcnJvcnxjaGVja3BvaW50LiplcnJvcnxjcmFzaCByZWNvdmVyeXxzdGFydHVwLipmYWlsfGF1dGhlbnRpY2F0aW9uLipmYWlsfGFjY2VzcyBkZW5pZWQnCmpvdXJuYWxfZXJyb3JzPSQoam91cm5hbGN0bCAtLXNpbmNlICIkTE9HX0xPT0tCQUNLIiAtLW5vLXBhZ2VyIDI+L2Rldi9udWxsIHwgZ3JlcCAtRWkgIiRFUlJPUl9QQVRURVJOIiB8IHRhaWwgLW4gMjAgfHwgdHJ1ZSkKaWYgWyAtbiAiJGpvdXJuYWxfZXJyb3JzIiBdOyB0aGVuIHByaW50X3dhcm5pbmcgJ1BvdGVudGlhbCBkYXRhYmFzZS1yZWxhdGVkIGlzc3VlcyBmb3VuZCBpbiB0aGUgc3lzdGVtIGpvdXJuYWw6JzsgcHJpbnRmICclc1xuJyAiJGpvdXJuYWxfZXJyb3JzIiB8IHNlZCAncy9eLyAgLyc7IExPR19XQVJOSU5HX0NPVU5UPSQoKExPR19XQVJOSU5HX0NPVU5UICsgMSkpOyBlbHNlIHByaW50X29rICdObyBtYXRjaGluZyBjcml0aWNhbCBwYXR0ZXJucyBmb3VuZCBpbiB0aGUgc3lzdGVtIGpvdXJuYWwuJzsgZmkKZm9yIGtleSBpbiAiJHtEQVRBQkFTRV9LRVlTW0BdfSI7IGRvCiAgICBbICIke0RCX0RFVEVDVEVEWyRrZXldfSIgLWVxIDEgXSB8fCBjb250aW51ZQogICAgbG9nX3BhdGg9IiR7REJfTE9HU1ska2V5XX0iOyBbIC1lICIkbG9nX3BhdGgiIF0gfHwgY29udGludWUKICAgIG5hdGl2ZV9lcnJvcnM9JChncmVwIC1SaGlFICIkRVJST1JfUEFUVEVSTiIgIiRsb2dfcGF0aCIgMj4vZGV2L251bGwgfCB0YWlsIC1uIDEwIHx8IHRydWUpCiAgICBpZiBbIC1uICIkbmF0aXZlX2Vycm9ycyIgXTsgdGhlbiBwcmludF93YXJuaW5nICIke0RCX0xBQkVMWyRrZXldfSBuYXRpdmUgbG9ncyBjb250YWluIG1hdGNoaW5nIGVycm9yIHBhdHRlcm5zOiI7IHByaW50ZiAnJXNcbicgIiRuYXRpdmVfZXJyb3JzIiB8IHNlZCAncy9eLyAgLyc7IExPR19XQVJOSU5HX0NPVU5UPSQoKExPR19XQVJOSU5HX0NPVU5UICsgMSkpOyBmaQpkb25lCnByaW50ZiAnXG4nCgpwcmludF9zZWN0aW9uICcxMS45IFBPU1RHUkVTUUwgQVNTRVNTTUVOVCcKaWYgWyAiJHtEQl9ERVRFQ1RFRFtwb3N0Z3Jlc3FsXX0iIC1lcSAxIF07IHRoZW4KICAgIGNvbW1hbmRfZXhpc3RzIHBnX2xzY2x1c3RlcnMgJiYgcGdfbHNjbHVzdGVycyAyPi9kZXYvbnVsbCB8fCBwcmludF9pbmZvICdwZ19sc2NsdXN0ZXJzIGlzIHVuYXZhaWxhYmxlLicKICAgIHByaW50ZiAnXG4nCiAgICBjb21tYW5kX2V4aXN0cyBwZ19pc3JlYWR5ICYmIHBnX2lzcmVhZHkgMj4mMSB8fCBwcmludF9pbmZvICdwZ19pc3JlYWR5IGlzIHVuYXZhaWxhYmxlLicKZWxzZSBwcmludF9pbmZvICdQb3N0Z3JlU1FMIGlzIG5vdCBkZXRlY3RlZC4nOyBmaQpwcmludGYgJ1xuJwoKcHJpbnRfc2VjdGlvbiAnMTEuMTAgTVlTUUwgLyBNQVJJQURCIEFTU0VTU01FTlQnCmlmIFsgIiR7REJfREVURUNURURbbXlzcWxdfSIgLWVxIDEgXSB8fCBbICIke0RCX0RFVEVDVEVEW21hcmlhZGJdfSIgLWVxIDEgXTsgdGhlbgogICAgY29tbWFuZF9leGlzdHMgbXlzcWxhZG1pbiAmJiBteXNxbGFkbWluIC0tY29ubmVjdC10aW1lb3V0PTIgcGluZyAyPiYxIHwgaGVhZCAtbiAzIHx8IHByaW50X2luZm8gJ215c3FsYWRtaW4gaXMgdW5hdmFpbGFibGUuJwogICAgc29ja2V0X2xpbmVzPSQoZ3JlcCAtUmhpRSAnXltbOnNwYWNlOl1dKnNvY2tldFtbOnNwYWNlOl1dKj0nIC9ldGMvbXlzcWwgMj4vZGV2L251bGwgfCBzZWQgJ3MvXltbOnNwYWNlOl1dKi8vJyB8IGhlYWQgLW4gNSB8fCB0cnVlKQogICAgWyAtbiAiJHNvY2tldF9saW5lcyIgXSAmJiB7IHByaW50ZiAnICBDb25maWd1cmVkIHNvY2tldCBlbnRyaWVzOlxuJzsgcHJpbnRmICclc1xuJyAiJHNvY2tldF9saW5lcyIgfCBzZWQgJ3MvXi8gICAgLyc7IH0KZWxzZSBwcmludF9pbmZvICdNeVNRTCBhbmQgTWFyaWFEQiBhcmUgbm90IGRldGVjdGVkLic7IGZpCnByaW50ZiAnXG4nCgpwcmludF9zZWN0aW9uICcxMS4xMSBSRURJUyBBU1NFU1NNRU5UJwppZiBbICIke0RCX0RFVEVDVEVEW3JlZGlzXX0iIC1lcSAxIF07IHRoZW4KICAgIGlmIGNvbW1hbmRfZXhpc3RzIHJlZGlzLWNsaTsgdGhlbgogICAgICAgIGlmIHJlZGlzLWNsaSAtaCAxMjcuMC4wLjEgLXAgNjM3OSAtLW5vLWF1dGgtd2FybmluZyBwaW5nIDI+L2Rldi9udWxsIHwgZ3JlcCAtRnhxIFBPTkc7IHRoZW4KICAgICAgICAgICAgcHJpbnRfb2sgJ1JlZGlzIHJlc3BvbmRlZCB0byB1bmF1dGhlbnRpY2F0ZWQgbG9jYWwgUElORy4nCiAgICAgICAgICAgIHJlZGlzX2luZm89JChyZWRpcy1jbGkgLWggMTI3LjAuMC4xIC1wIDYzNzkgLS1uby1hdXRoLXdhcm5pbmcgSU5GTyBtZW1vcnkgMj4vZGV2L251bGwgfCBncmVwIC1FICdeKHVzZWRfbWVtb3J5X2h1bWFufG1heG1lbW9yeV9odW1hbnxtYXhtZW1vcnlfcG9saWN5KTonIHwgdHIgLWQgJ1xyJyB8fCB0cnVlKQogICAgICAgICAgICBbIC1uICIkcmVkaXNfaW5mbyIgXSAmJiBwcmludGYgJyVzXG4nICIkcmVkaXNfaW5mbyIgfCBzZWQgJ3MvXi8gIC8nCiAgICAgICAgZWxzZSBwcmludF9pbmZvICdSZWRpcyBkaWQgbm90IGFsbG93IGFuIHVuYXV0aGVudGljYXRlZCBsb2NhbCBoZWFsdGggcXVlcnkuJzsgZmkKICAgIGVsc2UgcHJpbnRfaW5mbyAncmVkaXMtY2xpIGlzIHVuYXZhaWxhYmxlLic7IGZpCmVsc2UgcHJpbnRfaW5mbyAnUmVkaXMgaXMgbm90IGRldGVjdGVkLic7IGZpCnByaW50ZiAnXG4nCgpwcmludF9zZWN0aW9uICcxMS4xMiBSRVBMSUNBVElPTiAvIENMVVNURVIgSU5ESUNBVE9SUycKUkVQTElDQVRJT05fUEFUVEVSTj0ncHJpbWFyeV9jb25uaW5mb3xzdGFuZGJ5X21vZGV8c3luY2hyb25vdXNfc3RhbmRieV9uYW1lc3x3YWxfbGV2ZWx8aG90X3N0YW5kYnl8c2VydmVyX2lkfGxvZ19iaW58cmVsYXlfbG9nfHJlYWRfb25seXx3c3JlcF9vbnx3c3JlcF9jbHVzdGVyfGdhbGVyYXxzZW50aW5lbCBtb25pdG9yfGNsdXN0ZXItZW5hYmxlZHxyZXBsaWNhb2Z8cmVwbGljYVNldHxjbHVzdGVyLm5hbWV8ZGlzY292ZXJ5LnNlZWRfaG9zdHMnCnJlcGxpY2F0aW9uX291dHB1dD0kKGdyZXAgLVJuaUUgIiRSRVBMSUNBVElPTl9QQVRURVJOIiAvZXRjL3Bvc3RncmVzcWwgL2V0Yy9teXNxbCAvZXRjL3JlZGlzIC9ldGMvZWxhc3RpY3NlYXJjaCAvZXRjL29wZW5zZWFyY2ggL2V0Yy9tb25nb2QuY29uZiAyPi9kZXYvbnVsbCB8IGdyZXAgLUVpdiAncGFzc3dvcmR8c2VjcmV0fHRva2VufGtleWZpbGV8Y3JlZGVudGlhbCcgfCBoZWFkIC1uIDMwIHx8IHRydWUpCmlmIFsgLW4gIiRyZXBsaWNhdGlvbl9vdXRwdXQiIF07IHRoZW4gcHJpbnRfaW5mbyAnUmVwbGljYXRpb24gb3IgY2x1c3RlcmluZyBpbmRpY2F0b3JzIHdlcmUgZm91bmQ6JzsgcHJpbnRmICclc1xuJyAiJHJlcGxpY2F0aW9uX291dHB1dCIgfCBzZWQgJ3MvXi8gIC8nOyBlbHNlIHByaW50X2luZm8gJ05vIGNsZWFyIHJlcGxpY2F0aW9uIG9yIGNsdXN0ZXJpbmcgaW5kaWNhdG9ycyBmb3VuZCBpbiBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gcGF0aHMuJzsgZmkKcHJpbnRmICdcbicKCnByaW50X3NlY3Rpb24gJzExLjEzIEJBQ0tVUCBBU1NFU1NNRU5UJwpjcm9uX2JhY2t1cF9vdXRwdXQ9JChncmVwIC1SbmlFICdwZ19kdW1wfHBnX2Jhc2ViYWNrdXB8bXlzcWxkdW1wfG1hcmlhZGItZHVtcHxtb25nb2R1bXB8cmVkaXMuKihyZGJ8YW9mKXxjbGlja2hvdXNlLipiYWNrdXB8aW5mbHV4LipiYWNrdXB8Y3Fsc2guKmNvcHl8YmFja3VwJyAvZXRjL2Nyb24uZCAvZXRjL2Nyb24uZGFpbHkgL2V0Yy9jcm9uLmhvdXJseSAvZXRjL2Nyb24ud2Vla2x5IC9ldGMvY3Jvbi5tb250aGx5IC92YXIvc3Bvb2wvY3Jvbi9jcm9udGFicyAyPi9kZXYvbnVsbCB8IGdyZXAgLUVpdiAncGFzc3dvcmR8c2VjcmV0fHRva2VufGNyZWRlbnRpYWwnIHwgaGVhZCAtbiAyMCB8fCB0cnVlKQp0aW1lcl9iYWNrdXBfb3V0cHV0PSQoc3lzdGVtY3RsIGxpc3QtdGltZXJzIC0tYWxsIC0tbm8tcGFnZXIgMj4vZGV2L251bGwgfCBncmVwIC1FaSAnYmFja3VwfGR1bXB8cGdiYWNrcmVzdHx3YWwtZ3xib3JnfHJlc3RpYycgfCBoZWFkIC1uIDIwIHx8IHRydWUpCmJhY2t1cF9maWxlcz0kKGZpbmQgL3Zhci9iYWNrdXBzIC9iYWNrdXAgL3Nydi9iYWNrdXAgL29wdC9iYWNrdXAgL3Jvb3QgL2hvbWUgLXhkZXYgLXR5cGUgZiBcKCAtbmFtZSAnKi5zcWwnIC1vIC1uYW1lICcqLnNxbC5neicgLW8gLW5hbWUgJyouZHVtcCcgLW8gLW5hbWUgJyouYmFja3VwJyAtbyAtbmFtZSAnKi5yZGInIC1vIC1uYW1lICcqLmFvZicgLW8gLW5hbWUgJyouYnNvbicgLW8gLW5hbWUgJyoueGJzdHJlYW0nIFwpIC1wcmludGYgJyVUQHwlVFktJVRtLSVUZCAlVEg6JVRNfCVzfCVwXG4nIDI+L2Rldi9udWxsIHwgc29ydCAtdCd8JyAtazEsMW5yIHwgaGVhZCAtbiAxMCB8fCB0cnVlKQppZiBbIC1uICIkY3Jvbl9iYWNrdXBfb3V0cHV0IiBdOyB0aGVuIEJBQ0tVUF9TVEFUVVM9J0ZPVU5EJzsgcHJpbnRmICcgIENyb24gaW5kaWNhdG9yczpcbic7IHByaW50ZiAnJXNcbicgIiRjcm9uX2JhY2t1cF9vdXRwdXQiIHwgc2VkICdzL14vICAgIC8nOyBmaQppZiBbIC1uICIkdGltZXJfYmFja3VwX291dHB1dCIgXTsgdGhlbiBCQUNLVVBfU1RBVFVTPSdGT1VORCc7IHByaW50ZiAnICBzeXN0ZW1kIHRpbWVyIGluZGljYXRvcnM6XG4nOyBwcmludGYgJyVzXG4nICIkdGltZXJfYmFja3VwX291dHB1dCIgfCBzZWQgJ3MvXi8gICAgLyc7IGZpCmlmIFsgLW4gIiRiYWNrdXBfZmlsZXMiIF07IHRoZW4KICAgIEJBQ0tVUF9TVEFUVVM9J0ZPVU5EJzsgcHJpbnRmICcgIEJhY2t1cCBmaWxlczpcbicKICAgIHdoaWxlIElGUz0nfCcgcmVhZCAtciBlcG9jaCB0aW1lc3RhbXAgYnl0ZXMgcGF0aDsgZG8gWyAtbiAiJGVwb2NoIiBdIHx8IGNvbnRpbnVlOyBodW1hbl9zaXplPSQobnVtZm10IC0tdG89aWVjIC0tc3VmZml4PUIgIiRieXRlcyIgMj4vZGV2L251bGwgfHwgcHJpbnRmICclcyBieXRlcycgIiRieXRlcyIpOyBwcmludGYgJyAgICAlcyB8ICU4cyB8ICVzXG4nICIkdGltZXN0YW1wIiAiJGh1bWFuX3NpemUiICIkcGF0aCI7IGRvbmUgPDw8ICIkYmFja3VwX2ZpbGVzIgogICAgbmV3ZXN0X2Vwb2NoPSQocHJpbnRmICclc1xuJyAiJGJhY2t1cF9maWxlcyIgfCBoZWFkIC1uIDEgfCBjdXQgLWQnfCcgLWYxIHwgY3V0IC1kJy4nIC1mMSk7IG5ld2VzdF90aW1lc3RhbXA9JChwcmludGYgJyVzXG4nICIkYmFja3VwX2ZpbGVzIiB8IGhlYWQgLW4gMSB8IGN1dCAtZCd8JyAtZjIpCiAgICBpZiBbWyAiJG5ld2VzdF9lcG9jaCIgPX4gXlswLTldKyQgXV07IHRoZW4gbm93X2Vwb2NoPSQoZGF0ZSArJXMpOyBhZ2VfZGF5cz0kKCgobm93X2Vwb2NoIC0gbmV3ZXN0X2Vwb2NoKSAvIDg2NDAwKSk7IE5FV0VTVF9CQUNLVVA9IiR7bmV3ZXN0X3RpbWVzdGFtcH0gKCR7YWdlX2RheXN9IGRheShzKSBvbGQpIjsgWyAiJGFnZV9kYXlzIiAtZ3QgIiRCQUNLVVBfV0FSTklOR19EQVlTIiBdICYmIHByaW50X3dhcm5pbmcgIk5ld2VzdCBkaXNjb3ZlcmVkIGJhY2t1cCBmaWxlIGlzIG9sZGVyIHRoYW4gJHtCQUNLVVBfV0FSTklOR19EQVlTfSBkYXlzLiIgfHwgcHJpbnRfb2sgJ0EgcmVjZW50IGJhY2t1cCBmaWxlIHdhcyBkaXNjb3ZlcmVkLic7IGZpCmZpClsgIiRCQUNLVVBfU1RBVFVTIiA9ICdOT1QgRk9VTkQnIF0gJiYgcHJpbnRfd2FybmluZyAnTm8gZGF0YWJhc2UgYmFja3VwIGluZGljYXRvcnMgd2VyZSBmb3VuZCBpbiB0aGUgY2hlY2tlZCBsb2NhdGlvbnMuJwpwcmludGYgJ1xuJwoKcHJpbnRfc2VjdGlvbiAnMTEuMTQgREFUQUJBU0UgSEVBTFRIIFNVTU1BUlknCmZvciBrZXkgaW4gIiR7REFUQUJBU0VfS0VZU1tAXX0iOyBkbwogICAgWyAiJHtEQl9ERVRFQ1RFRFska2V5XX0iIC1lcSAxIF0gJiYgcHJpbnRmICcgICUtMjRzICVzXG4nICIke0RCX0xBQkVMWyRrZXldfSIgIiR7REJfU1RBVFVTWyRrZXldfSIgfHwgcHJpbnRmICcgICUtMjRzIE5PVCBJTlNUQUxMRURcbicgIiR7REJfTEFCRUxbJGtleV19Igpkb25lCmlmIFsgIiRTVE9SQUdFX0NSSVRJQ0FMX0NPVU5UIiAtZ3QgMCBdOyB0aGVuIFNUT1JBR0VfU1VNTUFSWT0nQ1JJVElDQUwnOyBlbGlmIFsgIiRTVE9SQUdFX1dBUk5JTkdfQ09VTlQiIC1ndCAwIF07IHRoZW4gU1RPUkFHRV9TVU1NQVJZPSdXQVJOSU5HJzsgZWxzZSBTVE9SQUdFX1NVTU1BUlk9J09LJzsgZmkKWyAiJEZBSUxFRF9TRVJWSUNFX0NPVU5UIiAtZ3QgMCBdICYmIFNFUlZJQ0VfU1VNTUFSWT0nQ1JJVElDQUwnIHx8IFNFUlZJQ0VfU1VNTUFSWT0nT0snClsgIiRMT0dfV0FSTklOR19DT1VOVCIgLWd0IDAgXSAmJiBMT0dfU1VNTUFSWT0nV0FSTklORycgfHwgTE9HX1NVTU1BUlk9J09LJwpwcmludGYgJ1xuICAlLTI0cyAlc1xuJyAnRGV0ZWN0ZWQgU2VydmljZXMnICIkREVURUNURURfQ09VTlQiCnByaW50ZiAnICAlLTI0cyAlc1xuJyAnTGlzdGVuaW5nIFBvcnRzJyAiJExJU1RFTklOR19QT1JUX0NPVU5UIgpwcmludGYgJyAgJS0yNHMgJXNcbicgJ1NlcnZpY2UgSGVhbHRoJyAiJFNFUlZJQ0VfU1VNTUFSWSIKcHJpbnRmICcgICUtMjRzICVzXG4nICdEYXRhYmFzZSBMb2dzJyAiJExPR19TVU1NQVJZIgpwcmludGYgJyAgJS0yNHMgJXNcbicgJ0RhdGFiYXNlIFN0b3JhZ2UnICIkU1RPUkFHRV9TVU1NQVJZIgpwcmludGYgJyAgJS0yNHMgJXNcbicgJ0JhY2t1cCBJbmRpY2F0b3JzJyAiJEJBQ0tVUF9TVEFUVVMiCnByaW50ZiAnICAlLTI0cyAlc1xuXG4nICdOZXdlc3QgQmFja3VwJyAiJE5FV0VTVF9CQUNLVVAiCmlmIFsgIiRGQUlMRURfU0VSVklDRV9DT1VOVCIgLWd0IDAgXSB8fCBbICIkU1RPUkFHRV9DUklUSUNBTF9DT1VOVCIgLWd0IDAgXTsgdGhlbiBwcmludF9jcml0aWNhbCAnRGF0YWJhc2UgYW5kIGRhdGEgc2VydmljZXMgcmVxdWlyZSBpbW1lZGlhdGUgYXR0ZW50aW9uLicKZWxpZiBbICIkTE9HX1dBUk5JTkdfQ09VTlQiIC1ndCAwIF0gfHwgWyAiJFNUT1JBR0VfV0FSTklOR19DT1VOVCIgLWd0IDAgXSB8fCBbICIkQkFDS1VQX1NUQVRVUyIgPSAnTk9UIEZPVU5EJyBdOyB0aGVuIHByaW50X3dhcm5pbmcgJ0RhdGFiYXNlIGFuZCBkYXRhIHNlcnZpY2VzIHJlcXVpcmUgcmV2aWV3LicKZWxzZSBwcmludF9vayAnTm8gY3JpdGljYWwgZGF0YWJhc2Ugb3IgZGF0YS1zZXJ2aWNlIGlzc3VlcyB3ZXJlIGRldGVjdGVkLic7IGZpCg==' | base64 -d | bash\r\n<\/pre><\/div>\r\n\r\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/env bash\r\n\r\n# ============================================================\r\n# 11. DATABASE &amp; DATA SERVICES ASSESSMENT\r\n# Read-only diagnostics for Debian \/ Ubuntu systems\r\n# No passwords are requested and no configuration is changed.\r\n# ============================================================\r\n\r\nset -u\r\nset -o pipefail\r\n\r\nif &#x5B; -t 1 ] &amp;&amp; &#x5B; &quot;${TERM:-dumb}&quot; != &quot;dumb&quot; ]; then\r\n    GREEN='\\033&#x5B;0;32m'; RED='\\033&#x5B;0;31m'; YELLOW='\\033&#x5B;1;33m'\r\n    BLUE='\\033&#x5B;0;34m'; CYAN='\\033&#x5B;0;36m'; NC='\\033&#x5B;0m'\r\nelse\r\n    GREEN=''; RED=''; YELLOW=''; BLUE=''; CYAN=''; NC=''\r\nfi\r\n\r\nprint_main_header() { printf '%b\\n\\n' &quot;${BLUE}==================== 11. DATABASE &amp; DATA SERVICES ====================${NC}&quot;; }\r\nprint_section() { printf '%b\\n' &quot;${BLUE}--- $1 ---${NC}&quot;; }\r\nprint_ok() { printf '%b\\n' &quot;${GREEN}&#x5B;OK]${NC} $1&quot;; }\r\nprint_info() { printf '%b\\n' &quot;${CYAN}&#x5B;INFO]${NC} $1&quot;; }\r\nprint_warning() { printf '%b\\n' &quot;${YELLOW}&#x5B;WARNING]${NC} $1&quot;; }\r\nprint_critical() { printf '%b\\n' &quot;${RED}&#x5B;CRITICAL]${NC} $1&quot;; }\r\ncommand_exists() { command -v &quot;$1&quot; &gt;\/dev\/null 2&gt;&amp;1; }\r\n\r\nFILESYSTEM_WARNING_THRESHOLD=80\r\nFILESYSTEM_CRITICAL_THRESHOLD=90\r\nBACKUP_WARNING_DAYS=7\r\nLOG_LOOKBACK='24 hours ago'\r\n\r\ndeclare -A DB_LABEL DB_SERVICE DB_COMMAND DB_PORTS DB_CONFIG DB_DATA DB_LOGS\r\ndeclare -A DB_DETECTED DB_STATUS DB_VERSION\r\n\r\nDATABASE_KEYS=(postgresql mysql mariadb mongodb redis elasticsearch opensearch clickhouse influxdb cassandra rabbitmq)\r\n\r\nDB_LABEL&#x5B;postgresql]='PostgreSQL'; DB_SERVICE&#x5B;postgresql]='postgresql'; DB_COMMAND&#x5B;postgresql]='psql'; DB_PORTS&#x5B;postgresql]='5432'; DB_CONFIG&#x5B;postgresql]='\/etc\/postgresql'; DB_DATA&#x5B;postgresql]='\/var\/lib\/postgresql'; DB_LOGS&#x5B;postgresql]='\/var\/log\/postgresql'\r\nDB_LABEL&#x5B;mysql]='MySQL'; DB_SERVICE&#x5B;mysql]='mysql'; DB_COMMAND&#x5B;mysql]='mysql'; DB_PORTS&#x5B;mysql]='3306'; DB_CONFIG&#x5B;mysql]='\/etc\/mysql'; DB_DATA&#x5B;mysql]='\/var\/lib\/mysql'; DB_LOGS&#x5B;mysql]='\/var\/log\/mysql'\r\nDB_LABEL&#x5B;mariadb]='MariaDB'; DB_SERVICE&#x5B;mariadb]='mariadb'; DB_COMMAND&#x5B;mariadb]='mariadb'; DB_PORTS&#x5B;mariadb]='3306'; DB_CONFIG&#x5B;mariadb]='\/etc\/mysql'; DB_DATA&#x5B;mariadb]='\/var\/lib\/mysql'; DB_LOGS&#x5B;mariadb]='\/var\/log\/mysql'\r\nDB_LABEL&#x5B;mongodb]='MongoDB'; DB_SERVICE&#x5B;mongodb]='mongod'; DB_COMMAND&#x5B;mongodb]='mongosh'; DB_PORTS&#x5B;mongodb]='27017'; DB_CONFIG&#x5B;mongodb]='\/etc\/mongod.conf'; DB_DATA&#x5B;mongodb]='\/var\/lib\/mongodb'; DB_LOGS&#x5B;mongodb]='\/var\/log\/mongodb'\r\nDB_LABEL&#x5B;redis]='Redis'; DB_SERVICE&#x5B;redis]='redis-server'; DB_COMMAND&#x5B;redis]='redis-cli'; DB_PORTS&#x5B;redis]='6379'; DB_CONFIG&#x5B;redis]='\/etc\/redis'; DB_DATA&#x5B;redis]='\/var\/lib\/redis'; DB_LOGS&#x5B;redis]='\/var\/log\/redis'\r\nDB_LABEL&#x5B;elasticsearch]='Elasticsearch'; DB_SERVICE&#x5B;elasticsearch]='elasticsearch'; DB_COMMAND&#x5B;elasticsearch]='elasticsearch'; DB_PORTS&#x5B;elasticsearch]='9200 9300'; DB_CONFIG&#x5B;elasticsearch]='\/etc\/elasticsearch'; DB_DATA&#x5B;elasticsearch]='\/var\/lib\/elasticsearch'; DB_LOGS&#x5B;elasticsearch]='\/var\/log\/elasticsearch'\r\nDB_LABEL&#x5B;opensearch]='OpenSearch'; DB_SERVICE&#x5B;opensearch]='opensearch'; DB_COMMAND&#x5B;opensearch]='opensearch'; DB_PORTS&#x5B;opensearch]='9200 9300'; DB_CONFIG&#x5B;opensearch]='\/etc\/opensearch'; DB_DATA&#x5B;opensearch]='\/var\/lib\/opensearch'; DB_LOGS&#x5B;opensearch]='\/var\/log\/opensearch'\r\nDB_LABEL&#x5B;clickhouse]='ClickHouse'; DB_SERVICE&#x5B;clickhouse]='clickhouse-server'; DB_COMMAND&#x5B;clickhouse]='clickhouse-client'; DB_PORTS&#x5B;clickhouse]='8123 9000'; DB_CONFIG&#x5B;clickhouse]='\/etc\/clickhouse-server'; DB_DATA&#x5B;clickhouse]='\/var\/lib\/clickhouse'; DB_LOGS&#x5B;clickhouse]='\/var\/log\/clickhouse-server'\r\nDB_LABEL&#x5B;influxdb]='InfluxDB'; DB_SERVICE&#x5B;influxdb]='influxdb'; DB_COMMAND&#x5B;influxdb]='influx'; DB_PORTS&#x5B;influxdb]='8086'; DB_CONFIG&#x5B;influxdb]='\/etc\/influxdb'; DB_DATA&#x5B;influxdb]='\/var\/lib\/influxdb'; DB_LOGS&#x5B;influxdb]='\/var\/log\/influxdb'\r\nDB_LABEL&#x5B;cassandra]='Cassandra'; DB_SERVICE&#x5B;cassandra]='cassandra'; DB_COMMAND&#x5B;cassandra]='cqlsh'; DB_PORTS&#x5B;cassandra]='9042'; DB_CONFIG&#x5B;cassandra]='\/etc\/cassandra'; DB_DATA&#x5B;cassandra]='\/var\/lib\/cassandra'; DB_LOGS&#x5B;cassandra]='\/var\/log\/cassandra'\r\nDB_LABEL&#x5B;rabbitmq]='RabbitMQ'; DB_SERVICE&#x5B;rabbitmq]='rabbitmq-server'; DB_COMMAND&#x5B;rabbitmq]='rabbitmqctl'; DB_PORTS&#x5B;rabbitmq]='5672 15672'; DB_CONFIG&#x5B;rabbitmq]='\/etc\/rabbitmq'; DB_DATA&#x5B;rabbitmq]='\/var\/lib\/rabbitmq'; DB_LOGS&#x5B;rabbitmq]='\/var\/log\/rabbitmq'\r\n\r\nDETECTED_COUNT=0\r\nLISTENING_PORT_COUNT=0\r\nFAILED_SERVICE_COUNT=0\r\nLOG_WARNING_COUNT=0\r\nSTORAGE_WARNING_COUNT=0\r\nSTORAGE_CRITICAL_COUNT=0\r\nBACKUP_STATUS='NOT FOUND'\r\nNEWEST_BACKUP='N\/A'\r\n\r\nservice_unit_exists() {\r\n    local service=&quot;$1&quot;\r\n    systemctl list-unit-files --type=service --no-legend 2&gt;\/dev\/null | awk '{print $1}' | grep -Fxq &quot;${service}.service&quot;\r\n}\r\n\r\npackage_installed_matching() {\r\n    local pattern=&quot;$1&quot;\r\n    command_exists dpkg-query || return 1\r\n    dpkg-query -W -f='${Package}\\n' 2&gt;\/dev\/null | grep -Eiq &quot;$pattern&quot;\r\n}\r\n\r\ndetect_database() {\r\n    local key=&quot;$1&quot; service=&quot;${DB_SERVICE&#x5B;$1]}&quot; cmd=&quot;${DB_COMMAND&#x5B;$1]}&quot; config=&quot;${DB_CONFIG&#x5B;$1]}&quot; data=&quot;${DB_DATA&#x5B;$1]}&quot; detected=0\r\n    service_unit_exists &quot;$service&quot; &amp;&amp; detected=1\r\n    command_exists &quot;$cmd&quot; &amp;&amp; detected=1\r\n    { &#x5B; -e &quot;$config&quot; ] || &#x5B; -d &quot;$data&quot; ]; } &amp;&amp; detected=1\r\n    case &quot;$key&quot; in\r\n        postgresql) package_installed_matching '^postgresql(&#x5B;0-9.-]|$)|^postgresql-' &amp;&amp; detected=1 ;;\r\n        mysql) package_installed_matching '^mysql-server|^mysql-client' &amp;&amp; detected=1 ;;\r\n        mariadb) package_installed_matching '^mariadb-server|^mariadb-client' &amp;&amp; detected=1 ;;\r\n        mongodb) package_installed_matching '^mongodb|^mongodb-org' &amp;&amp; detected=1 ;;\r\n        redis) package_installed_matching '^redis-server|^redis-tools' &amp;&amp; detected=1 ;;\r\n        elasticsearch) package_installed_matching '^elasticsearch$' &amp;&amp; detected=1 ;;\r\n        opensearch) package_installed_matching '^opensearch' &amp;&amp; detected=1 ;;\r\n        clickhouse) package_installed_matching '^clickhouse-' &amp;&amp; detected=1 ;;\r\n        influxdb) package_installed_matching '^influxdb' &amp;&amp; detected=1 ;;\r\n        cassandra) package_installed_matching '^cassandra$' &amp;&amp; detected=1 ;;\r\n        rabbitmq) package_installed_matching '^rabbitmq-server$' &amp;&amp; detected=1 ;;\r\n    esac\r\n    DB_DETECTED&#x5B;$key]=&quot;$detected&quot;\r\n}\r\n\r\nget_service_state() {\r\n    local service=&quot;$1&quot; state\r\n    service_unit_exists &quot;$service&quot; || { printf 'NO UNIT'; return; }\r\n    state=$(systemctl is-active &quot;$service&quot; 2&gt;\/dev\/null || true)\r\n    case &quot;$state&quot; in\r\n        active) printf 'RUNNING' ;;\r\n        inactive) printf 'STOPPED' ;;\r\n        failed) printf 'FAILED' ;;\r\n        activating) printf 'STARTING' ;;\r\n        deactivating) printf 'STOPPING' ;;\r\n        *) printf '%s' &quot;${state^^}&quot; ;;\r\n    esac\r\n}\r\n\r\nget_version() {\r\n    local key=&quot;$1&quot; output=''\r\n    case &quot;$key&quot; in\r\n        postgresql) command_exists psql &amp;&amp; output=$(psql --version 2&gt;&amp;1 | head -n 1) ;;\r\n        mysql) command_exists mysql &amp;&amp; output=$(mysql --version 2&gt;&amp;1 | head -n 1) ;;\r\n        mariadb) command_exists mariadb &amp;&amp; output=$(mariadb --version 2&gt;&amp;1 | head -n 1) ;;\r\n        mongodb) if command_exists mongosh; then output=$(mongosh --version 2&gt;&amp;1 | head -n 1); elif command_exists mongod; then output=$(mongod --version 2&gt;&amp;1 | head -n 1); fi ;;\r\n        redis) command_exists redis-server &amp;&amp; output=$(redis-server --version 2&gt;&amp;1 | head -n 1) ;;\r\n        elasticsearch) if command_exists elasticsearch; then output=$(elasticsearch --version 2&gt;&amp;1 | head -n 1); elif &#x5B; -x \/usr\/share\/elasticsearch\/bin\/elasticsearch ]; then output=$(\/usr\/share\/elasticsearch\/bin\/elasticsearch --version 2&gt;&amp;1 | head -n 1); fi ;;\r\n        opensearch) if command_exists opensearch; then output=$(opensearch --version 2&gt;&amp;1 | head -n 1); elif &#x5B; -x \/usr\/share\/opensearch\/bin\/opensearch ]; then output=$(\/usr\/share\/opensearch\/bin\/opensearch --version 2&gt;&amp;1 | head -n 1); fi ;;\r\n        clickhouse) command_exists clickhouse-client &amp;&amp; output=$(clickhouse-client --version 2&gt;&amp;1 | head -n 1) ;;\r\n        influxdb) command_exists influx &amp;&amp; output=$(influx version 2&gt;&amp;1 | head -n 1) ;;\r\n        cassandra) command_exists cassandra &amp;&amp; output=$(cassandra -v 2&gt;&amp;1 | head -n 1) ;;\r\n        rabbitmq) command_exists rabbitmqctl &amp;&amp; output=$(rabbitmqctl version 2&gt;\/dev\/null | head -n 1) ;;\r\n    esac\r\n    &#x5B; -n &quot;$output&quot; ] &amp;&amp; printf '%s' &quot;$output&quot; || printf 'UNKNOWN'\r\n}\r\n\r\nprint_main_header\r\n\r\nprint_section '11.1 DATABASE DISCOVERY'\r\nfor key in &quot;${DATABASE_KEYS&#x5B;@]}&quot;; do\r\n    detect_database &quot;$key&quot;\r\n    if &#x5B; &quot;${DB_DETECTED&#x5B;$key]}&quot; -eq 1 ]; then\r\n        DETECTED_COUNT=$((DETECTED_COUNT + 1))\r\n        DB_VERSION&#x5B;$key]=&quot;$(get_version &quot;$key&quot;)&quot;\r\n        printf '  %-18s %bDETECTED%b\\n' &quot;${DB_LABEL&#x5B;$key]}&quot; &quot;$GREEN&quot; &quot;$NC&quot;\r\n        printf '    Version: %s\\n' &quot;${DB_VERSION&#x5B;$key]}&quot;\r\n    else\r\n        DB_VERSION&#x5B;$key]='N\/A'\r\n        printf '  %-18s NOT DETECTED\\n' &quot;${DB_LABEL&#x5B;$key]}&quot;\r\n    fi\r\ndone\r\n&#x5B; &quot;$DETECTED_COUNT&quot; -eq 0 ] &amp;&amp; print_info 'No supported database or data service was detected.' || print_ok &quot;$DETECTED_COUNT supported database or data service(s) detected.&quot;\r\nprintf '\\n'\r\n\r\nprint_section '11.2 SERVICE STATUS'\r\nfor key in &quot;${DATABASE_KEYS&#x5B;@]}&quot;; do\r\n    if &#x5B; &quot;${DB_DETECTED&#x5B;$key]}&quot; -ne 1 ]; then DB_STATUS&#x5B;$key]='NOT INSTALLED'; continue; fi\r\n    DB_STATUS&#x5B;$key]=&quot;$(get_service_state &quot;${DB_SERVICE&#x5B;$key]}&quot;)&quot;\r\n    case &quot;${DB_STATUS&#x5B;$key]}&quot; in\r\n        RUNNING) printf '  %-18s %bRUNNING%b\\n' &quot;${DB_LABEL&#x5B;$key]}&quot; &quot;$GREEN&quot; &quot;$NC&quot; ;;\r\n        FAILED) printf '  %-18s %bFAILED%b\\n' &quot;${DB_LABEL&#x5B;$key]}&quot; &quot;$RED&quot; &quot;$NC&quot;; FAILED_SERVICE_COUNT=$((FAILED_SERVICE_COUNT + 1)) ;;\r\n        STOPPED|'NO UNIT') printf '  %-18s %b%s%b\\n' &quot;${DB_LABEL&#x5B;$key]}&quot; &quot;$YELLOW&quot; &quot;${DB_STATUS&#x5B;$key]}&quot; &quot;$NC&quot; ;;\r\n        *) printf '  %-18s %s\\n' &quot;${DB_LABEL&#x5B;$key]}&quot; &quot;${DB_STATUS&#x5B;$key]}&quot; ;;\r\n    esac\r\ndone\r\n&#x5B; &quot;$FAILED_SERVICE_COUNT&quot; -gt 0 ] &amp;&amp; print_critical &quot;$FAILED_SERVICE_COUNT database service(s) are in failed state.&quot;\r\nprintf '\\n'\r\n\r\nprint_section '11.3 LISTENING PORTS'\r\nif ! command_exists ss; then\r\n    print_warning 'The ss command is unavailable.'\r\nelse\r\n    for key in &quot;${DATABASE_KEYS&#x5B;@]}&quot;; do\r\n        &#x5B; &quot;${DB_DETECTED&#x5B;$key]}&quot; -eq 1 ] || continue\r\n        for port in ${DB_PORTS&#x5B;$key]}; do\r\n            port_output=$(ss -lntup 2&gt;\/dev\/null | awk -v port=&quot;:$port&quot; '$5 ~ port&quot;$&quot; || $5 ~ port&quot;&#x5B;^0-9]&quot;')\r\n            if &#x5B; -n &quot;$port_output&quot; ]; then\r\n                LISTENING_PORT_COUNT=$((LISTENING_PORT_COUNT + 1))\r\n                printf '  %b%s%b (%s)\\n' &quot;$GREEN&quot; &quot;$port&quot; &quot;$NC&quot; &quot;${DB_LABEL&#x5B;$key]}&quot;\r\n                printf '%s\\n' &quot;$port_output&quot; | sed 's\/^\/    \/'\r\n            fi\r\n        done\r\n    done\r\n    &#x5B; &quot;$LISTENING_PORT_COUNT&quot; -eq 0 ] &amp;&amp; print_info 'No known database listening ports were detected.'\r\nfi\r\nprintf '\\n'\r\n\r\nprint_section '11.4 INSTALLED VERSIONS'\r\nfor key in &quot;${DATABASE_KEYS&#x5B;@]}&quot;; do &#x5B; &quot;${DB_DETECTED&#x5B;$key]}&quot; -eq 1 ] &amp;&amp; printf '  %-18s %s\\n' &quot;${DB_LABEL&#x5B;$key]}&quot; &quot;${DB_VERSION&#x5B;$key]}&quot;; done\r\n&#x5B; &quot;$DETECTED_COUNT&quot; -eq 0 ] &amp;&amp; print_info 'Nothing to report.'\r\nprintf '\\n'\r\n\r\nprint_section '11.5 DATABASE PROCESSES'\r\nPROCESS_PATTERN='postgres|postmaster|mysqld|mariadbd|mongod|redis-server|elasticsearch|opensearch|clickhouse-server|influxd|cassandra|beam.smp'\r\nprocess_output=$(ps -eo pid,ppid,user,%cpu,%mem,etime,comm,args --sort=-%cpu 2&gt;\/dev\/null | grep -Ei &quot;$PROCESS_PATTERN&quot; | grep -Ev 'grep -E|database_assessment' | head -n 25 || true)\r\n&#x5B; -n &quot;$process_output&quot; ] &amp;&amp; printf '%s\\n' &quot;$process_output&quot; || print_info 'No matching database processes were found.'\r\nprintf '\\n'\r\n\r\nprint_section '11.6 CONFIGURATION FILES'\r\nfor key in &quot;${DATABASE_KEYS&#x5B;@]}&quot;; do\r\n    &#x5B; &quot;${DB_DETECTED&#x5B;$key]}&quot; -eq 1 ] || continue\r\n    config=&quot;${DB_CONFIG&#x5B;$key]}&quot;\r\n    &#x5B; -e &quot;$config&quot; ] &amp;&amp; printf '  %-18s %s\\n' &quot;${DB_LABEL&#x5B;$key]}&quot; &quot;$config&quot; || printf '  %-18s NOT FOUND AT DEFAULT PATH\\n' &quot;${DB_LABEL&#x5B;$key]}&quot;\r\ndone\r\nprint_info 'Configuration contents are not displayed to avoid exposing credentials or secrets.'\r\nprintf '\\n'\r\n\r\nprint_section '11.7 STORAGE ASSESSMENT'\r\nfor key in &quot;${DATABASE_KEYS&#x5B;@]}&quot;; do\r\n    &#x5B; &quot;${DB_DETECTED&#x5B;$key]}&quot; -eq 1 ] || continue\r\n    data_dir=&quot;${DB_DATA&#x5B;$key]}&quot;; &#x5B; -d &quot;$data_dir&quot; ] || continue\r\n    size=$(du -shx &quot;$data_dir&quot; 2&gt;\/dev\/null | awk '{print $1}'); &#x5B; -n &quot;$size&quot; ] || size='PERMISSION DENIED'\r\n    fs_line=$(df -PTh &quot;$data_dir&quot; 2&gt;\/dev\/null | tail -n 1)\r\n    filesystem=$(printf '%s\\n' &quot;$fs_line&quot; | awk '{print $1}'); fs_type=$(printf '%s\\n' &quot;$fs_line&quot; | awk '{print $2}')\r\n    available=$(printf '%s\\n' &quot;$fs_line&quot; | awk '{print $5}'); use_pct=$(printf '%s\\n' &quot;$fs_line&quot; | awk '{gsub(&quot;%&quot;,&quot;&quot;,$6); print $6}')\r\n    mountpoint=$(printf '%s\\n' &quot;$fs_line&quot; | awk '{print $7}')\r\n    owner=$(stat -c '%U:%G' &quot;$data_dir&quot; 2&gt;\/dev\/null || printf 'UNKNOWN')\r\n    permissions=$(stat -c '%A (%a)' &quot;$data_dir&quot; 2&gt;\/dev\/null || printf 'UNKNOWN')\r\n    mount_options=$(findmnt -no OPTIONS -T &quot;$data_dir&quot; 2&gt;\/dev\/null || printf 'UNKNOWN')\r\n    printf '  %s\\n' &quot;${DB_LABEL&#x5B;$key]}&quot;\r\n    printf '    Data directory : %s\\n    Directory size : %s\\n    Owner           : %s\\n    Permissions     : %s\\n' &quot;$data_dir&quot; &quot;$size&quot; &quot;$owner&quot; &quot;$permissions&quot;\r\n    printf '    Filesystem      : %s (%s)\\n    Mount point     : %s\\n    Available       : %s\\n    Used            : %s%%\\n    Mount options   : %s\\n' &quot;${filesystem:-UNKNOWN}&quot; &quot;${fs_type:-UNKNOWN}&quot; &quot;${mountpoint:-UNKNOWN}&quot; &quot;${available:-UNKNOWN}&quot; &quot;${use_pct:-UNKNOWN}&quot; &quot;$mount_options&quot;\r\n    if &#x5B;&#x5B; &quot;${use_pct:-}&quot; =~ ^&#x5B;0-9]+$ ]]; then\r\n        if &#x5B; &quot;$use_pct&quot; -ge &quot;$FILESYSTEM_CRITICAL_THRESHOLD&quot; ]; then print_critical &quot;${DB_LABEL&#x5B;$key]} storage is ${use_pct}% used.&quot;; STORAGE_CRITICAL_COUNT=$((STORAGE_CRITICAL_COUNT + 1))\r\n        elif &#x5B; &quot;$use_pct&quot; -ge &quot;$FILESYSTEM_WARNING_THRESHOLD&quot; ]; then print_warning &quot;${DB_LABEL&#x5B;$key]} storage is ${use_pct}% used.&quot;; STORAGE_WARNING_COUNT=$((STORAGE_WARNING_COUNT + 1))\r\n        else print_ok &quot;${DB_LABEL&#x5B;$key]} storage utilization is within threshold.&quot;; fi\r\n    fi\r\n    case &quot;,$mount_options,&quot; in *,ro,*) print_critical &quot;$data_dir is mounted read-only.&quot;; STORAGE_CRITICAL_COUNT=$((STORAGE_CRITICAL_COUNT + 1)) ;; esac\r\n    printf '\\n'\r\ndone\r\nif &#x5B; -d \/var\/lib\/postgresql ]; then\r\n    while IFS= read -r wal_dir; do &#x5B; -n &quot;$wal_dir&quot; ] || continue; wal_size=$(du -shx &quot;$wal_dir&quot; 2&gt;\/dev\/null | awk '{print $1}'); printf '  PostgreSQL WAL: %s (%s)\\n' &quot;$wal_dir&quot; &quot;${wal_size:-UNKNOWN}&quot;; done &lt; &lt;(find \/var\/lib\/postgresql -type d -name pg_wal -print 2&gt;\/dev\/null | head -n 10)\r\nfi\r\nif &#x5B; -d \/var\/lib\/mysql ]; then\r\n    binlog_summary=$(find \/var\/lib\/mysql -maxdepth 1 -type f \\( -name 'mysql-bin.*' -o -name 'mariadb-bin.*' -o -name 'binlog.*' \\) -printf '%s\\n' 2&gt;\/dev\/null | awk '{sum+=$1; count++} END {if (count&gt;0) printf &quot;%d file(s), %.2f GiB&quot;, count, sum\/1024\/1024\/1024}')\r\n    &#x5B; -n &quot;$binlog_summary&quot; ] &amp;&amp; printf '  MySQL\/MariaDB binlogs: %s\\n' &quot;$binlog_summary&quot;\r\nfi\r\nprintf '\\n'\r\n\r\nprint_section '11.8 LOG ASSESSMENT'\r\nERROR_PATTERN='panic|fatal|corrupt|corruption|out of memory|oom|killed process|disk full|no space left|read-only file system|too many connections|replication.*error|wal.*error|checkpoint.*error|crash recovery|startup.*fail|authentication.*fail|access denied'\r\njournal_errors=$(journalctl --since &quot;$LOG_LOOKBACK&quot; --no-pager 2&gt;\/dev\/null | grep -Ei &quot;$ERROR_PATTERN&quot; | tail -n 20 || true)\r\nif &#x5B; -n &quot;$journal_errors&quot; ]; then print_warning 'Potential database-related issues found in the system journal:'; printf '%s\\n' &quot;$journal_errors&quot; | sed 's\/^\/  \/'; LOG_WARNING_COUNT=$((LOG_WARNING_COUNT + 1)); else print_ok 'No matching critical patterns found in the system journal.'; fi\r\nfor key in &quot;${DATABASE_KEYS&#x5B;@]}&quot;; do\r\n    &#x5B; &quot;${DB_DETECTED&#x5B;$key]}&quot; -eq 1 ] || continue\r\n    log_path=&quot;${DB_LOGS&#x5B;$key]}&quot;; &#x5B; -e &quot;$log_path&quot; ] || continue\r\n    native_errors=$(grep -RhiE &quot;$ERROR_PATTERN&quot; &quot;$log_path&quot; 2&gt;\/dev\/null | tail -n 10 || true)\r\n    if &#x5B; -n &quot;$native_errors&quot; ]; then print_warning &quot;${DB_LABEL&#x5B;$key]} native logs contain matching error patterns:&quot;; printf '%s\\n' &quot;$native_errors&quot; | sed 's\/^\/  \/'; LOG_WARNING_COUNT=$((LOG_WARNING_COUNT + 1)); fi\r\ndone\r\nprintf '\\n'\r\n\r\nprint_section '11.9 POSTGRESQL ASSESSMENT'\r\nif &#x5B; &quot;${DB_DETECTED&#x5B;postgresql]}&quot; -eq 1 ]; then\r\n    command_exists pg_lsclusters &amp;&amp; pg_lsclusters 2&gt;\/dev\/null || print_info 'pg_lsclusters is unavailable.'\r\n    printf '\\n'\r\n    command_exists pg_isready &amp;&amp; pg_isready 2&gt;&amp;1 || print_info 'pg_isready is unavailable.'\r\nelse print_info 'PostgreSQL is not detected.'; fi\r\nprintf '\\n'\r\n\r\nprint_section '11.10 MYSQL \/ MARIADB ASSESSMENT'\r\nif &#x5B; &quot;${DB_DETECTED&#x5B;mysql]}&quot; -eq 1 ] || &#x5B; &quot;${DB_DETECTED&#x5B;mariadb]}&quot; -eq 1 ]; then\r\n    command_exists mysqladmin &amp;&amp; mysqladmin --connect-timeout=2 ping 2&gt;&amp;1 | head -n 3 || print_info 'mysqladmin is unavailable.'\r\n    socket_lines=$(grep -RhiE '^&#x5B;&#x5B;:space:]]*socket&#x5B;&#x5B;:space:]]*=' \/etc\/mysql 2&gt;\/dev\/null | sed 's\/^&#x5B;&#x5B;:space:]]*\/\/' | head -n 5 || true)\r\n    &#x5B; -n &quot;$socket_lines&quot; ] &amp;&amp; { printf '  Configured socket entries:\\n'; printf '%s\\n' &quot;$socket_lines&quot; | sed 's\/^\/    \/'; }\r\nelse print_info 'MySQL and MariaDB are not detected.'; fi\r\nprintf '\\n'\r\n\r\nprint_section '11.11 REDIS ASSESSMENT'\r\nif &#x5B; &quot;${DB_DETECTED&#x5B;redis]}&quot; -eq 1 ]; then\r\n    if command_exists redis-cli; then\r\n        if redis-cli -h 127.0.0.1 -p 6379 --no-auth-warning ping 2&gt;\/dev\/null | grep -Fxq PONG; then\r\n            print_ok 'Redis responded to unauthenticated local PING.'\r\n            redis_info=$(redis-cli -h 127.0.0.1 -p 6379 --no-auth-warning INFO memory 2&gt;\/dev\/null | grep -E '^(used_memory_human|maxmemory_human|maxmemory_policy):' | tr -d '\\r' || true)\r\n            &#x5B; -n &quot;$redis_info&quot; ] &amp;&amp; printf '%s\\n' &quot;$redis_info&quot; | sed 's\/^\/  \/'\r\n        else print_info 'Redis did not allow an unauthenticated local health query.'; fi\r\n    else print_info 'redis-cli is unavailable.'; fi\r\nelse print_info 'Redis is not detected.'; fi\r\nprintf '\\n'\r\n\r\nprint_section '11.12 REPLICATION \/ CLUSTER INDICATORS'\r\nREPLICATION_PATTERN='primary_conninfo|standby_mode|synchronous_standby_names|wal_level|hot_standby|server_id|log_bin|relay_log|read_only|wsrep_on|wsrep_cluster|galera|sentinel monitor|cluster-enabled|replicaof|replicaSet|cluster.name|discovery.seed_hosts'\r\nreplication_output=$(grep -RniE &quot;$REPLICATION_PATTERN&quot; \/etc\/postgresql \/etc\/mysql \/etc\/redis \/etc\/elasticsearch \/etc\/opensearch \/etc\/mongod.conf 2&gt;\/dev\/null | grep -Eiv 'password|secret|token|keyfile|credential' | head -n 30 || true)\r\nif &#x5B; -n &quot;$replication_output&quot; ]; then print_info 'Replication or clustering indicators were found:'; printf '%s\\n' &quot;$replication_output&quot; | sed 's\/^\/  \/'; else print_info 'No clear replication or clustering indicators found in default configuration paths.'; fi\r\nprintf '\\n'\r\n\r\nprint_section '11.13 BACKUP ASSESSMENT'\r\ncron_backup_output=$(grep -RniE 'pg_dump|pg_basebackup|mysqldump|mariadb-dump|mongodump|redis.*(rdb|aof)|clickhouse.*backup|influx.*backup|cqlsh.*copy|backup' \/etc\/cron.d \/etc\/cron.daily \/etc\/cron.hourly \/etc\/cron.weekly \/etc\/cron.monthly \/var\/spool\/cron\/crontabs 2&gt;\/dev\/null | grep -Eiv 'password|secret|token|credential' | head -n 20 || true)\r\ntimer_backup_output=$(systemctl list-timers --all --no-pager 2&gt;\/dev\/null | grep -Ei 'backup|dump|pgbackrest|wal-g|borg|restic' | head -n 20 || true)\r\nbackup_files=$(find \/var\/backups \/backup \/srv\/backup \/opt\/backup \/root \/home -xdev -type f \\( -name '*.sql' -o -name '*.sql.gz' -o -name '*.dump' -o -name '*.backup' -o -name '*.rdb' -o -name '*.aof' -o -name '*.bson' -o -name '*.xbstream' \\) -printf '%T@|%TY-%Tm-%Td %TH:%TM|%s|%p\\n' 2&gt;\/dev\/null | sort -t'|' -k1,1nr | head -n 10 || true)\r\nif &#x5B; -n &quot;$cron_backup_output&quot; ]; then BACKUP_STATUS='FOUND'; printf '  Cron indicators:\\n'; printf '%s\\n' &quot;$cron_backup_output&quot; | sed 's\/^\/    \/'; fi\r\nif &#x5B; -n &quot;$timer_backup_output&quot; ]; then BACKUP_STATUS='FOUND'; printf '  systemd timer indicators:\\n'; printf '%s\\n' &quot;$timer_backup_output&quot; | sed 's\/^\/    \/'; fi\r\nif &#x5B; -n &quot;$backup_files&quot; ]; then\r\n    BACKUP_STATUS='FOUND'; printf '  Backup files:\\n'\r\n    while IFS='|' read -r epoch timestamp bytes path; do &#x5B; -n &quot;$epoch&quot; ] || continue; human_size=$(numfmt --to=iec --suffix=B &quot;$bytes&quot; 2&gt;\/dev\/null || printf '%s bytes' &quot;$bytes&quot;); printf '    %s | %8s | %s\\n' &quot;$timestamp&quot; &quot;$human_size&quot; &quot;$path&quot;; done &lt;&lt;&lt; &quot;$backup_files&quot;\r\n    newest_epoch=$(printf '%s\\n' &quot;$backup_files&quot; | head -n 1 | cut -d'|' -f1 | cut -d'.' -f1); newest_timestamp=$(printf '%s\\n' &quot;$backup_files&quot; | head -n 1 | cut -d'|' -f2)\r\n    if &#x5B;&#x5B; &quot;$newest_epoch&quot; =~ ^&#x5B;0-9]+$ ]]; then now_epoch=$(date +%s); age_days=$(((now_epoch - newest_epoch) \/ 86400)); NEWEST_BACKUP=&quot;${newest_timestamp} (${age_days} day(s) old)&quot;; &#x5B; &quot;$age_days&quot; -gt &quot;$BACKUP_WARNING_DAYS&quot; ] &amp;&amp; print_warning &quot;Newest discovered backup file is older than ${BACKUP_WARNING_DAYS} days.&quot; || print_ok 'A recent backup file was discovered.'; fi\r\nfi\r\n&#x5B; &quot;$BACKUP_STATUS&quot; = 'NOT FOUND' ] &amp;&amp; print_warning 'No database backup indicators were found in the checked locations.'\r\nprintf '\\n'\r\n\r\nprint_section '11.14 DATABASE HEALTH SUMMARY'\r\nfor key in &quot;${DATABASE_KEYS&#x5B;@]}&quot;; do\r\n    &#x5B; &quot;${DB_DETECTED&#x5B;$key]}&quot; -eq 1 ] &amp;&amp; printf '  %-24s %s\\n' &quot;${DB_LABEL&#x5B;$key]}&quot; &quot;${DB_STATUS&#x5B;$key]}&quot; || printf '  %-24s NOT INSTALLED\\n' &quot;${DB_LABEL&#x5B;$key]}&quot;\r\ndone\r\nif &#x5B; &quot;$STORAGE_CRITICAL_COUNT&quot; -gt 0 ]; then STORAGE_SUMMARY='CRITICAL'; elif &#x5B; &quot;$STORAGE_WARNING_COUNT&quot; -gt 0 ]; then STORAGE_SUMMARY='WARNING'; else STORAGE_SUMMARY='OK'; fi\r\n&#x5B; &quot;$FAILED_SERVICE_COUNT&quot; -gt 0 ] &amp;&amp; SERVICE_SUMMARY='CRITICAL' || SERVICE_SUMMARY='OK'\r\n&#x5B; &quot;$LOG_WARNING_COUNT&quot; -gt 0 ] &amp;&amp; LOG_SUMMARY='WARNING' || LOG_SUMMARY='OK'\r\nprintf '\\n  %-24s %s\\n' 'Detected Services' &quot;$DETECTED_COUNT&quot;\r\nprintf '  %-24s %s\\n' 'Listening Ports' &quot;$LISTENING_PORT_COUNT&quot;\r\nprintf '  %-24s %s\\n' 'Service Health' &quot;$SERVICE_SUMMARY&quot;\r\nprintf '  %-24s %s\\n' 'Database Logs' &quot;$LOG_SUMMARY&quot;\r\nprintf '  %-24s %s\\n' 'Database Storage' &quot;$STORAGE_SUMMARY&quot;\r\nprintf '  %-24s %s\\n' 'Backup Indicators' &quot;$BACKUP_STATUS&quot;\r\nprintf '  %-24s %s\\n\\n' 'Newest Backup' &quot;$NEWEST_BACKUP&quot;\r\nif &#x5B; &quot;$FAILED_SERVICE_COUNT&quot; -gt 0 ] || &#x5B; &quot;$STORAGE_CRITICAL_COUNT&quot; -gt 0 ]; then print_critical 'Database and data services require immediate attention.'\r\nelif &#x5B; &quot;$LOG_WARNING_COUNT&quot; -gt 0 ] || &#x5B; &quot;$STORAGE_WARNING_COUNT&quot; -gt 0 ] || &#x5B; &quot;$BACKUP_STATUS&quot; = 'NOT FOUND' ]; then print_warning 'Database and data services require review.'\r\nelse print_ok 'No critical database or data-service issues were detected.'; fi\r\n<\/pre><\/div>\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"862\" class=\"wp-image-1228\" style=\"width: 800px;\" src=\"https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-01-950x1024.png\" alt=\"\" srcset=\"https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-01-950x1024.png 950w, https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-01-278x300.png 278w, https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-01-768x828.png 768w, https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-01-1200x1294.png 1200w, https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-01.png 1215w\" sizes=\"(max-width: 800px) 85vw, 800px\" \/><\/figure><\/div>\r\n\r\n<div class=\"wp-block-image\">\r\n<figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"550\" class=\"wp-image-1229\" style=\"width: 800px;\" src=\"https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-02-1024x704.png\" alt=\"\" srcset=\"https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-02-1024x704.png 1024w, https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-02-300x206.png 300w, https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-02-768x528.png 768w, https:\/\/itgen.itbumper.com\/wp-content\/uploads\/2026\/07\/011_debian_databases-02.png 1099w\" sizes=\"(max-width: 800px) 85vw, 800px\" \/><\/figure><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[21,26],"tags":[],"_links":{"self":[{"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/pages\/1226"}],"collection":[{"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1226"}],"version-history":[{"count":4,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/pages\/1226\/revisions"}],"predecessor-version":[{"id":1233,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=\/wp\/v2\/pages\/1226\/revisions\/1233"}],"wp:attachment":[{"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1226"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1226"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itgen.itbumper.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1226"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}