├── moat370 ├── LICENSE ├── .gitignore ├── database │ ├── postgres │ │ ├── postgres_post.sql │ │ ├── postgres_table_desc.sql │ │ ├── postgres_load_variable.sql │ │ ├── postgres_run_raw.sql │ │ ├── postgres_run_html.sql │ │ └── postgres_pre.sql │ ├── oracle │ │ ├── oracle_load_variable.sql │ │ ├── oracle_post.sql │ │ ├── oracle_table_desc.sql │ │ ├── oracle_pre.sh │ │ ├── oracle_reset.sql │ │ ├── oracle_run_raw.sql │ │ ├── sqlcl_run_html.sql │ │ ├── oracle_run_html.sql │ │ ├── oracle_run_csv.sql │ │ ├── oracle_post.sh │ │ └── oracle_pre.sql │ └── mysql │ │ ├── mysql_table_desc.sql │ │ ├── mysql_load_variable.sql │ │ ├── mysql_run_csv.sql │ │ ├── mysql_pre.sql │ │ └── mysql_load_variable_all.sql ├── .gitattributes ├── cfg │ ├── version.cfg │ ├── moat370_html_footer.html │ ├── moat370_fc_define_files.cfg │ ├── moat370_html_encoded.html │ ├── moat370_html_header.html │ └── moat370_html_encoded_index.html ├── js │ ├── sorttable.js │ ├── tablefilter │ │ └── style │ │ │ ├── themes │ │ │ ├── blank.png │ │ │ ├── upsimple.png │ │ │ ├── downsimple.png │ │ │ └── btn_clear_filters.png │ │ │ └── tablefilter.css │ ├── vs.css │ ├── style.css │ ├── decode.min.js │ ├── decode.js │ ├── gunzip.js │ └── aes.js ├── README.md ├── sh │ ├── offline_functions.sh │ ├── moat370_0c_post.sh │ ├── moat370_functions_datatypes.sh │ ├── moat370_0a_main.sh │ ├── moat370_fc_parse_parameters.sh │ ├── moat370_functions_csv_parser.sh │ ├── csv-parser.awk │ ├── mysql_functions.sh │ ├── sqlplus_functions.sh │ ├── postgres_functions.sh │ ├── sqlcl_functions.sh │ └── moat370_fc_check_config.sh └── LICENSE-3RD-PARTY ├── .gitignore ├── sql ├── pgedb360_0b_post.sql └── pgedb360_0a_pre.sql ├── jpg ├── pgedb360.ico └── pgedb360.png ├── pgedb360.sh ├── sh ├── pgedb360_security.sh ├── pgedb360_0b_pre.sh ├── pgedb360_bg_writer.sh ├── pgedb360_tool_logs.sh ├── pgedb360_database_configuration.sh ├── pgedb360_checkpoints.sh ├── pgedb360_replica.sh ├── pgedb360_sessions.sh ├── pgedb360_database_state.sh ├── pgedb360_buffer_cache.sh ├── pgedb360_locks.sh └── pgedb360_sqls.sh ├── cfg ├── 00_config.cfg ├── 00_sections.csv └── 00_software.cfg ├── README.md ├── LICENSE └── CONTRIBUTING.md /moat370/LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /moat370/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | output/ -------------------------------------------------------------------------------- /moat370/database/postgres/postgres_post.sql: -------------------------------------------------------------------------------- 1 | \set -------------------------------------------------------------------------------- /sql/pgedb360_0b_post.sql: -------------------------------------------------------------------------------- 1 | \timing off 2 | \pset footer on -------------------------------------------------------------------------------- /moat370/database/oracle/oracle_load_variable.sql: -------------------------------------------------------------------------------- 1 | SPOOL &1. 2 | DEFINE &2. 3 | SPOOL OFF -------------------------------------------------------------------------------- /jpg/pgedb360.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shane-borden/pgedb360/master/jpg/pgedb360.ico -------------------------------------------------------------------------------- /jpg/pgedb360.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shane-borden/pgedb360/master/jpg/pgedb360.png -------------------------------------------------------------------------------- /moat370/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /moat370/database/mysql/mysql_table_desc.sql: -------------------------------------------------------------------------------- 1 | tee %%file_name%% 2 | desc %%table_name%%; 3 | notee -------------------------------------------------------------------------------- /moat370/database/postgres/postgres_table_desc.sql: -------------------------------------------------------------------------------- 1 | \out %%file_name%% 2 | \d %%table_name%% 3 | \out -------------------------------------------------------------------------------- /moat370/cfg/version.cfg: -------------------------------------------------------------------------------- 1 | moat370_fw_vYYNN='v21.02' 2 | moat370_fw_vrsn="${moat370_fw_vYYNN} (2021-04-01)" 3 | -------------------------------------------------------------------------------- /moat370/database/postgres/postgres_load_variable.sql: -------------------------------------------------------------------------------- 1 | \out %%file_name%% 2 | \qecho :%%var_name%% 3 | \out -------------------------------------------------------------------------------- /moat370/js/sorttable.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shane-borden/pgedb360/master/moat370/js/sorttable.js -------------------------------------------------------------------------------- /moat370/database/oracle/oracle_post.sql: -------------------------------------------------------------------------------- 1 | ALTER SESSION SET SQL_TRACE = FALSE; 2 | 3 | DEF; 4 | SHOW PARAMETERS; -------------------------------------------------------------------------------- /moat370/database/oracle/oracle_table_desc.sql: -------------------------------------------------------------------------------- 1 | SPO &1. APP 2 | SET LIN &2. 3 | DESC &3. 4 | SET HEA OFF LIN 32767 5 | SPO OFF -------------------------------------------------------------------------------- /moat370/database/mysql/mysql_load_variable.sql: -------------------------------------------------------------------------------- 1 | tee %%file_name%% 2 | SELECT concat('%%var_name%%=''',@%%var_name%%,'''') as ''; 3 | notee -------------------------------------------------------------------------------- /moat370/database/mysql/mysql_run_csv.sql: -------------------------------------------------------------------------------- 1 | tee %%file_name%% 2 | source %%query_file%% 3 | notee 4 | 5 | tee %%error_file%% 6 | SHOW ERRORS; 7 | notee -------------------------------------------------------------------------------- /moat370/js/tablefilter/style/themes/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shane-borden/pgedb360/master/moat370/js/tablefilter/style/themes/blank.png -------------------------------------------------------------------------------- /moat370/database/postgres/postgres_run_raw.sql: -------------------------------------------------------------------------------- 1 | \out %%file_name%% 2 | \include %%query_file%% 3 | \out 4 | 5 | \out %%error_file%% 6 | \qecho :ERROR 7 | \out -------------------------------------------------------------------------------- /moat370/js/tablefilter/style/themes/upsimple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shane-borden/pgedb360/master/moat370/js/tablefilter/style/themes/upsimple.png -------------------------------------------------------------------------------- /moat370/js/tablefilter/style/themes/downsimple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shane-borden/pgedb360/master/moat370/js/tablefilter/style/themes/downsimple.png -------------------------------------------------------------------------------- /moat370/js/tablefilter/style/themes/btn_clear_filters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shane-borden/pgedb360/master/moat370/js/tablefilter/style/themes/btn_clear_filters.png -------------------------------------------------------------------------------- /pgedb360.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # pgedb360 tool 3 | echo "Start pgedb360." 4 | 5 | export moat370_pre_sw_output_fdr=`pwd`/output 6 | 7 | export SHELLOPTS 8 | bash ./moat370/sh/moat370_0a_main.sh "$@" 9 | -------------------------------------------------------------------------------- /moat370/database/postgres/postgres_run_html.sql: -------------------------------------------------------------------------------- 1 | \pset format html 2 | \out %%file_name%% 3 | \include %%query_file%% 4 | \out 5 | \pset format aligned 6 | 7 | \out %%error_file%% 8 | \qecho :ERROR 9 | \out -------------------------------------------------------------------------------- /moat370/database/oracle/oracle_pre.sh: -------------------------------------------------------------------------------- 1 | fc_def_empty_var moat370_conf_incl_opatch 2 | fc_set_value_var_nvl 'moat370_conf_incl_opatch' "${moat370_conf_incl_opatch}" 'N' 3 | fc_validate_variable moat370_conf_incl_opatch Y_N -------------------------------------------------------------------------------- /moat370/cfg/moat370_html_footer.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | ${moat370_sw_copyright} ${moat370_sw_name} ${moat370_sw_vrsn} based on moat370 ${moat370_fw_vrsn}. Timestamp: ${moat370_time_stamp} ${total_hours} 4 | 5 | 6 | -------------------------------------------------------------------------------- /moat370/cfg/moat370_fc_define_files.cfg: -------------------------------------------------------------------------------- 1 | moat370_fdr_sh="${moat370_fdr}/sh" 2 | moat370_fdr_js="${moat370_fdr}/js" 3 | moat370_fdr_cfg="${moat370_fdr}/cfg" 4 | 5 | ## Define Function Files 6 | 7 | fc_check_config="${moat370_fdr_sh}/moat370_fc_check_config.sh" 8 | fc_parse_parameters="${moat370_fdr_sh}/moat370_fc_parse_parameters.sh" -------------------------------------------------------------------------------- /moat370/database/oracle/oracle_reset.sql: -------------------------------------------------------------------------------- 1 | SET HEA ON 2 | SET LIN 32767 3 | SET NEWP NONE 4 | SET PAGES ${moat370_def_sql_maxrows} 5 | SET LONG 32000000 6 | SET LONGC 4000 7 | SET WRA ON 8 | SET TRIMS ON 9 | SET TRIM ON 10 | SET TI OFF 11 | SET TIMI OFF 12 | SET ARRAY 1000 13 | SET NUM 20 14 | SET SQLBL ON 15 | SET BLO . 16 | SET RECSEP OFF -------------------------------------------------------------------------------- /sh/pgedb360_security.sh: -------------------------------------------------------------------------------- 1 | ## Queries By Abel Macias and contributions. 2 | 3 | title='Users with weak password' 4 | sql_text=$(cat <<'END_HEREDOC' 5 | select usename as "Users with weak password" from pg_shadow where passwd='md5'||md5(usename||usename) 6 | END_HEREDOC 7 | ) 8 | fc_exec_item 9 | 10 | title='Users with weak password' 11 | sql_text='\deu+' 12 | output_type='text' 13 | fc_exec_item 14 | -------------------------------------------------------------------------------- /moat370/database/oracle/oracle_run_raw.sql: -------------------------------------------------------------------------------- 1 | -- This code must run the query on target database and return the output in CSV format. 2 | 3 | -- get sql 4 | GET &1. 5 | 6 | -- header 7 | SET HEA OFF FEED OFF TERM OFF PAGES 50000 VER OFF 8 | SPO &2. 9 | / 10 | SPO OFF 11 | 12 | SELECT prev_sql_id moat370_prev_sql_id, 13 | prev_child_number moat370_prev_child_number 14 | FROM v$session 15 | WHERE sid = SYS_CONTEXT('USERENV', 'SID') 16 | / -------------------------------------------------------------------------------- /moat370/database/postgres/postgres_pre.sql: -------------------------------------------------------------------------------- 1 | \set hosts_count 1 2 | 3 | create temp table cores(num_cores integer); 4 | copy cores(num_cores) from program 'grep processor /proc/cpuinfo | wc -l'; 5 | select num_cores as avg_core_count from cores \gset 6 | drop table cores; 7 | 8 | \set avg_thread_count :avg_core_count 9 | 10 | SELECT current_database() as database_name \gset 11 | 12 | \set host_name :HOST 13 | 14 | \set db_version :VERSION_NAME -------------------------------------------------------------------------------- /moat370/README.md: -------------------------------------------------------------------------------- 1 | # Mother of All Tools 370 2 | 3 | MOAT370 is an evolution of MOAT369, based purely in shell script and can run against multiple database vendors (not only Oracle as its predecessor). 4 | 5 | The goal of this framework is to allow anyone to easily extract information from the Database or the Operating System into a fancy HTML format with tables and charts, with minimal coding required. 6 | 7 | For usage sample, check [smp361](https://github.com/dbarj/smp361). -------------------------------------------------------------------------------- /moat370/database/oracle/sqlcl_run_html.sql: -------------------------------------------------------------------------------- 1 | -- This code must run the query on target database and return the output in CSV format. 2 | 3 | -- get sql 4 | GET &1. 5 | 6 | -- header 7 | SET HEA ON FEED OFF TERM OFF PAGES 50000 VER OFF 8 | SET SQLFORMAT HTML 9 | SPO &2. 10 | / 11 | SPO OFF 12 | SET SQLFORMAT DEFAULT 13 | 14 | SELECT prev_sql_id moat370_prev_sql_id, 15 | prev_child_number moat370_prev_child_number 16 | FROM v$session 17 | WHERE sid = SYS_CONTEXT('USERENV', 'SID') 18 | / -------------------------------------------------------------------------------- /moat370/database/oracle/oracle_run_html.sql: -------------------------------------------------------------------------------- 1 | -- This code must run the query on target database and return the output in CSV format. 2 | 3 | -- get sql 4 | GET &1. 5 | 6 | -- header 7 | SET HEA ON FEED OFF TERM OFF PAGES 50000 VER OFF 8 | SET MARK HTML ON SPOOL OFF 9 | SPO &2. 10 | / 11 | SPO OFF 12 | SET MARK HTML OFF 13 | 14 | SELECT prev_sql_id moat370_prev_sql_id, 15 | prev_child_number moat370_prev_child_number 16 | FROM v$session 17 | WHERE sid = SYS_CONTEXT('USERENV', 'SID') 18 | / -------------------------------------------------------------------------------- /moat370/database/oracle/oracle_run_csv.sql: -------------------------------------------------------------------------------- 1 | -- This code must run the query on target database and return the output in CSV format. 2 | 3 | -- get sql 4 | GET &1. 5 | 6 | -- header 7 | SET HEA ON FEED OFF TERM OFF PAGES 50000 VER OFF 8 | SET MARKUP CSV ON DELIMITER ',' QUOTE ON 9 | SPO &2. 10 | / 11 | SPO OFF 12 | SET MARKUP CSV OFF 13 | 14 | SELECT prev_sql_id moat370_prev_sql_id, 15 | prev_child_number moat370_prev_child_number 16 | FROM v$session 17 | WHERE sid = SYS_CONTEXT('USERENV', 'SID') 18 | / -------------------------------------------------------------------------------- /sql/pgedb360_0a_pre.sql: -------------------------------------------------------------------------------- 1 | \pset footer off 2 | \timing on 3 | 4 | -- Check if pg_buffercache module is enabled. 5 | SELECT count(1) as pgedb360_pg_buffercache 6 | from pg_extension 7 | where extname='pg_buffercache' 8 | \gset 9 | 10 | -- Check if pg_stat_statements module is enabled. 11 | SELECT count(1) as pgedb360_pg_stat_statements 12 | from pg_extension 13 | where extname='pg_stat_statements' 14 | \gset 15 | 16 | -- Check if pgsentinel module is enabled. 17 | SELECT count(1) as pgedb360_pg_ash 18 | from pg_extension 19 | where extname='pgsentinel' 20 | \gset 21 | -------------------------------------------------------------------------------- /sh/pgedb360_0b_pre.sh: -------------------------------------------------------------------------------- 1 | ############################## 2 | # fc_load_variable converts a database variable into a shellscript variable. 3 | fc_load_variable pgedb360_pg_stat_statements 4 | fc_load_variable pgedb360_pg_ash 5 | fc_load_variable SERVER_VERSION_NUM pgedb360_server_version_num 6 | ############################## 7 | 8 | # skip_if_no_pg_stat_statements will be empty ONLY if pg_stat_statements module exists 9 | fc_set_value_var_decode skip_if_no_pg_stat_statements "${pgedb360_pg_stat_statements}" 0 '-' '' 10 | 11 | # skip_if_no_pg_ash will be empty ONLY if pgsentinel module exists 12 | fc_set_value_var_decode skip_if_no_pg_ash "${pgedb360_pg_ash}" 0 '-' '' 13 | -------------------------------------------------------------------------------- /sh/pgedb360_bg_writer.sh: -------------------------------------------------------------------------------- 1 | ## Queries By Abel Macias and contributions. 2 | 3 | sql_text_bkp='select * from pg_stat_bgwriter' 4 | 5 | title='BG Writer Perf - Snap 1' 6 | sql_text=${sql_text_bkp} 7 | fc_exec_item 8 | 9 | sleep 10 10 | 11 | title='BG Writer Perf - Snap 2' 12 | sql_text=${sql_text_bkp} 13 | fc_exec_item 14 | 15 | sleep 10 16 | 17 | title='BG Writer Perf - Snap 3' 18 | sql_text=${sql_text_bkp} 19 | fc_exec_item 20 | 21 | sleep 10 22 | 23 | title='BG Writer Perf - Snap 4' 24 | sql_text=${sql_text_bkp} 25 | fc_exec_item 26 | 27 | sleep 10 28 | 29 | title='BG Writer Perf - Snap 5' 30 | sql_text=${sql_text_bkp} 31 | fc_exec_item 32 | 33 | unset sql_text_bkp -------------------------------------------------------------------------------- /moat370/cfg/moat370_html_encoded.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | 18 | 19 |
-------------------------------------------------------------------------------- /cfg/00_config.cfg: -------------------------------------------------------------------------------- 1 | ## moat370 configuration file. for those cases where you must change moat370 functionality 2 | 3 | ## /*************************** ok to modify (if really needed) ****************************/ 4 | 5 | ## report column, or section, or range of columns or range of sections i.e. 3, 3-4, 3a, 3a-4c, 3-4c, 3c-4 / null means all (default) 6 | moat370_sections='' 7 | 8 | ## history days (default 31) 9 | moat370_conf_days='90' 10 | 11 | ## range of dates below superceed history days when values are other than YYYY-MM-DD 12 | moat370_conf_date_from='YYYY-MM-DD' 13 | moat370_conf_date_to='YYYY-MM-DD' 14 | 15 | ## defines if the output will be compressed 16 | moat370_conf_compress_html='ON' 17 | 18 | ## 19 | moat370_conf_tablefilter='Y' 20 | moat370_def_sql_format='N' 21 | moat370_def_sql_highlight='Y' 22 | moat370_def_sql_wait_secs=60 # Max seconds to wait on a SQL. -------------------------------------------------------------------------------- /moat370/cfg/moat370_html_header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | ${title}${title_suffix} 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /moat370/database/mysql/mysql_pre.sql: -------------------------------------------------------------------------------- 1 | -- get average number of CPUs 2 | select @sum_cpu_count := `COUNT` from INFORMATION_SCHEMA.INNODB_METRICS where name = 'cpu_n'; 3 | 4 | -- get total number of CPUs 5 | SET @avg_cpu_count := @sum_cpu_count; 6 | 7 | -- get average number of Cores 8 | SET @avg_core_count := @sum_cpu_count; 9 | 10 | -- get average number of Threads 11 | SET @avg_thread_count := @sum_cpu_count; 12 | 13 | -- get number of Hosts 14 | SET @hosts_count := 1; 15 | 16 | -- get spid 17 | SELECT @moat370_spid := `x` FROM (select CONNECTION_ID() x) t; 18 | 19 | -- get threadid 20 | SELECT @thread_id := `THREAD_ID` FROM performance_schema.threads where PROCESSLIST_ID = @moat370_spid; 21 | 22 | -- get database name 23 | SELECT @database_name := `x` FROM (select IFNULL(DATABASE(),'root') x) t; 24 | 25 | -- get host name 26 | SET @host_name := @@hostname; 27 | 28 | -- get rdbms version 29 | SELECT @db_version := `x` FROM (select VERSION() x) t; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pgedb360 2 | 3 | pgedb360 is a tool to get PostgreSQL overall activity, generate the execution plan of the top sqls and get all the relevant information that the planner used to generate that plan. 4 | 5 | pgedb360 is based on [MOAT370 Framework](https://github.com/dbarj/moat370). 6 | 7 | ## Execution Steps ## 8 | 9 | 1. Download and unzip latest pgedb360 version and, navigate to the root of pgedb360-master directory: 10 | 11 | ``` 12 | $ wget -O pgedb360.zip https://github.com/dbarj/pgedb360/archive/master.zip 13 | $ unzip pgedb360.zip 14 | $ cd pgedb360-master/ 15 | ``` 16 | 17 | 2. Execute pgedb360.sh: 18 | 19 | ``` 20 | $ read -s PGPASSWORD 21 | xxxxxx 22 | $ export PGPASSWORD 23 | $ bash pgedb360.sh '-h localhost -p 5432 -d postgres -U postgres' 24 | ``` 25 | 26 | ## Results ## 27 | 28 | 1. Unzip output **pgedb360_dbname_hostname_YYYYMMDD_HH24MI.zip** into a directory on your PC. 29 | 30 | 2. Review main html file **00001_pgedb360_dbname_index.html**. -------------------------------------------------------------------------------- /moat370/cfg/moat370_html_encoded_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17 | 18 | 19 | 20 |
21 |
22 | ${moat370_sw_name} 23 |
24 | 25 |
26 |
-------------------------------------------------------------------------------- /cfg/00_sections.csv: -------------------------------------------------------------------------------- 1 | ## Add or remove new Sections in this file. No need to update anywhere else. 2 | ## Use "," as field separator 3 | ## Format: Section ID [1a - 9z], File Sufix Name, Section Description, Skip Variables (If last field is empty or its variables return NULL, sql WILL be executed) 4 | ## 5 | 1a,pgedb360_database_state.sh,System under observation 6 | 1b,pgedb360_database_configuration.sh,DB Configuration 7 | 1c,pgedb360_schemas.sh,Schema Objects 8 | 2a,pgedb360_buffer_cache.sh,Buffer Cache 9 | 2b,pgedb360_checkpoints.sh,Checkpoints 10 | 2c,pgedb360_bg_writer.sh,BG Writer 11 | 2d,pgedb360_locks.sh,Locks 12 | 3a,pgedb360_security.sh,Security 13 | 3b,pgedb360_sqls.sh,SQL Section,${skip_if_no_pg_stat_statements} 14 | 3c,pgedb360_sessions.sh,Idle and Active Sessions Profile 15 | 3d,pgedb360_replica.sh,Replica 16 | 4a,pgedb360_tool_logs.sh,Tool Logs 17 | ## 18 | ## Note: You can optionally have sections 0a_pre.sh and 0b_post.sh (not defined on this csv). 19 | ## They are not mandatory and they instruct moat to run only once a initial sql before all of them (0a) or after all of them (0b). -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Rodrigo Jorge 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /moat370/database/mysql/mysql_load_variable_all.sql: -------------------------------------------------------------------------------- 1 | select @query := `x` 2 | from ( 3 | select GROUP_CONCAT(concat('SELECT concat(''',VARIABLE_NAME,'='''''',@',VARIABLE_NAME,','''''''') as ''''') separator ' UNION ') x 4 | from performance_schema.user_variables_by_thread 5 | where THREAD_ID=@THREAD_ID 6 | and VARIABLE_NAME<>'query' 7 | ) t; 8 | PREPARE stmt1 FROM @query; 9 | tee %%file_name%% 10 | EXECUTE stmt1; 11 | notee 12 | DEALLOCATE PREPARE stmt1; 13 | 14 | -- tee %%file_name%% 15 | -- SELECT concat('sum_cpu_count=''',@sum_cpu_count,'''') as ''; 16 | -- SELECT concat('avg_cpu_count=''',@avg_cpu_count,'''') as ''; 17 | -- SELECT concat('avg_core_count=''',@avg_core_count,'''') as ''; 18 | -- SELECT concat('avg_thread_count=''',@avg_thread_count,'''') as ''; 19 | -- SELECT concat('hosts_count=''',@hosts_count,'''') as ''; 20 | -- SELECT concat('moat370_spid=''',@moat370_spid,'''') as ''; 21 | -- SELECT concat('thread_id=''',@thread_id,'''') as ''; 22 | -- SELECT concat('database_name=''',@database_name,'''') as ''; 23 | -- SELECT concat('host_name=''',@host_name,'''') as ''; 24 | -- SELECT concat('db_version=''',@db_version,'''') as ''; 25 | -- notee -------------------------------------------------------------------------------- /moat370/js/vs.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Visual Studio-like style based on original C# coloring by Jason Diamond 4 | 5 | */ 6 | .hljs { 7 | display: block; 8 | overflow-x: auto; 9 | padding: 0.5em; 10 | background: white; 11 | color: black; 12 | } 13 | 14 | .hljs-comment, 15 | .hljs-quote, 16 | .hljs-variable { 17 | color: #008000; 18 | } 19 | 20 | .hljs-keyword, 21 | .hljs-selector-tag, 22 | .hljs-built_in, 23 | .hljs-name, 24 | .hljs-tag { 25 | color: #00f; 26 | } 27 | 28 | .hljs-string, 29 | .hljs-title, 30 | .hljs-section, 31 | .hljs-attribute, 32 | .hljs-literal, 33 | .hljs-template-tag, 34 | .hljs-template-variable, 35 | .hljs-type, 36 | .hljs-addition { 37 | color: #a31515; 38 | } 39 | 40 | .hljs-deletion, 41 | .hljs-selector-attr, 42 | .hljs-selector-pseudo, 43 | .hljs-meta { 44 | color: #2b91af; 45 | } 46 | 47 | .hljs-doctag { 48 | color: #808080; 49 | } 50 | 51 | .hljs-attr { 52 | color: #f00; 53 | } 54 | 55 | .hljs-symbol, 56 | .hljs-bullet, 57 | .hljs-link { 58 | color: #00b0e8; 59 | } 60 | 61 | 62 | .hljs-emphasis { 63 | font-style: italic; 64 | } 65 | 66 | .hljs-strong { 67 | font-weight: bold; 68 | } 69 | -------------------------------------------------------------------------------- /cfg/00_software.cfg: -------------------------------------------------------------------------------- 1 | #*********************** software configuration (do not modify ) ************************/ 2 | 3 | moat370_sw_name='pgedb360' 4 | moat370_sw_logo_file='pgedb360.png' 5 | moat370_sw_icon_file='pgedb360.ico' 6 | moat370_sw_title_desc='360-degree comprehensive report on an PostgreSQL database' 7 | moat370_sw_url='https://github.com/dbarj/pgedb360' 8 | moat370_sw_rpt_cols='4' 9 | moat370_sw_logo_fdr='jpg' 10 | moat370_sw_dbtool='Y' 11 | moat370_sw_db_type='postgres' 12 | 13 | moat370_sw_logo_title="pgedb360 is a tool that provides a 360-degree view of PostgreSQL. 14 | Its output can be used as a foundation for a database review. 15 | 16 | With pgedb360, a user with limited access can acquire a good understanding of an PostgreSQL 17 | without having to log into the server directly. 18 | This capability is of great value to developers, system administrators, 3rd party consultants, Auditors 19 | or any remote user with restricted access." 20 | 21 | moat370_sw_vYYNN='v21.01' 22 | moat370_sw_vrsn="${moat370_sw_vYYNN} (2021-04-02)" 23 | 24 | moat370_sw_copyright='pgedb360 (c) 2021, MIT' 25 | moat370_sw_author='Abel Macias, Rodrigo Jorge' 26 | moat370_sw_email='' 27 | 28 | moat370_sw_enc_sql='N' 29 | 30 | moat370_sw_param1=custom 31 | moat370_sw_param1_var=moat370_sw_db_conn_params 32 | 33 | moat370_sw_param2=section 34 | 35 | #*************************** ok to modify (if really needed) ****************************/ -------------------------------------------------------------------------------- /moat370/database/oracle/oracle_post.sh: -------------------------------------------------------------------------------- 1 | fc_oracle_tkprof 2 | 3 | echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 | 5 | ## Alert log (3 methods) 6 | db_name_upper=$(upper_var "${database_name}") 7 | db_name_lower=$(lower_var "${database_name}") 8 | 9 | cp "${background_dump_dest}"/alert_${db_name_upper}*.log "${moat370_sw_output_fdr}/" >> "${moat370_log3}" 2> "${moat370_log3}" 10 | cp "${background_dump_dest}"/alert_${db_name_lower}*.log "${moat370_sw_output_fdr}/" >> "${moat370_log3}" 2> "${moat370_log3}" 11 | cp "${background_dump_dest}"/alert_${_connect_identifier}.log "${moat370_sw_output_fdr}/" >> "${moat370_log3}" 2> "${moat370_log3}" 12 | 13 | ## Altered to be compatible with SunOS: 14 | ## HOS rename alert_ ${moat370_alert}_ alert_*.log >> ${moat370_log3} 15 | 16 | ls -1 "${moat370_sw_output_fdr}"/alert_*.log 2> "${moat370_log3}" | while read line || [ -n "$line" ] 17 | do 18 | mv "$line" ${moat370_alert}_$(basename "$line") 19 | done >> "${moat370_log3}" 20 | 21 | fc_zip_file "${moat370_zip_filename}" "${moat370_alert}*.log" 22 | 23 | if [ "${moat370_conf_incl_opatch}" = 'Y' ] 24 | then 25 | if ls $ORACLE_HOME/cfgtoollogs/opatch/opatch* 1> /dev/null 2>&1 26 | then 27 | zip -j "${moat370_opatch}" $ORACLE_HOME/cfgtoollogs/opatch/opatch* >> "${moat370_log3}" 28 | fi 29 | fi 30 | 31 | if [ -f "${moat370_opatch}" ] 32 | then 33 | fc_zip_file "${moat370_zip_filename}" "${moat370_opatch}" 34 | fi 35 | 36 | ############ -------------------------------------------------------------------------------- /sh/pgedb360_tool_logs.sh: -------------------------------------------------------------------------------- 1 | fc_clean_file_name "moat370_log" "moat370_file_nopath" "PATH" 2 | title="File: ${moat370_file_nopath}" 3 | 4 | input_file=${moat370_log} 5 | one_spool_text_file_rename='N' 6 | 7 | output_type="text" 8 | fc_exec_item 9 | 10 | ##-------------- 11 | 12 | fc_clean_file_name "moat370_log2" "moat370_file_nopath" "PATH" 13 | title="File: ${moat370_file_nopath}" 14 | 15 | input_file=${moat370_log2} 16 | one_spool_text_file_rename='N' 17 | 18 | output_type="text" 19 | fc_exec_item 20 | 21 | ##-------------- 22 | 23 | fc_clean_file_name "moat370_log3" "moat370_file_nopath" "PATH" 24 | title="File: ${moat370_file_nopath}" 25 | 26 | input_file=${moat370_log3} 27 | one_spool_text_file_rename='N' 28 | 29 | output_type="text" 30 | fc_exec_item 31 | 32 | ##-------------- 33 | 34 | fc_seq_output_file v_database_in_file 35 | 36 | fc_clean_file_name "v_database_in_file" "moat370_file_nopath" "PATH" 37 | title="Database Input Log: ${moat370_file_nopath}" 38 | 39 | input_file=${v_database_in_file} 40 | one_spool_text_file_rename='N' 41 | 42 | output_type="text" 43 | fc_exec_item 44 | 45 | ##-------------- 46 | 47 | fc_seq_output_file v_database_out_file 48 | 49 | fc_clean_file_name "v_database_out_file" "moat370_file_nopath" "PATH" 50 | title="Database Output Log: ${moat370_file_nopath}" 51 | 52 | input_file=${v_database_out_file} 53 | one_spool_text_file_rename='N' 54 | 55 | output_type="text" 56 | fc_exec_item 57 | 58 | ##-------------- 59 | 60 | unset moat370_file_nopath -------------------------------------------------------------------------------- /moat370/js/style.css: -------------------------------------------------------------------------------- 1 | body {font:10pt Arial,Helvetica,Geneva,sans-serif; color:black; background:white;} 2 | h1 {font-size:16pt; font-weight:bold; color:#336699; border-bottom:1px solid #336699; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} 3 | h2 {font-size:14pt; font-weight:bold; color:#336699; margin-top:4pt; margin-bottom:0pt;} 4 | h3 {font-size:12pt; font-weight:bold; color:#336699; margin-top:4pt; margin-bottom:0pt;} 5 | pre {font:8pt monospace,Monaco,"Courier New",Courier;} 6 | a {color:#663300;} 7 | table {font-size:8pt; border-collapse:collapse; empty-cells:show; white-space:nowrap; border:1px solid #336699;} 8 | li {font-size:8pt; color:black; padding-left:4px; padding-right:4px; padding-bottom:2px;} 9 | th {font-weight:bold; color:white; background:#0066CC; padding-left:4px; padding-right:4px; padding-bottom:2px;} 10 | tr {color:black; background:white;} 11 | tr:hover {color:white; background:#0066CC;} 12 | tr.main {color:black; background:white;} 13 | tr.main:hover {color:black; background:white;} 14 | td {vertical-align:top; border:1px solid #336699;} 15 | td.c {text-align:center;} 16 | font.n {font-size:8pt; font-style:italic; color:#336699;} 17 | font.f {font-size:8pt; color:#999999; border-top:1px solid #336699; margin-top:30pt;} 18 | div.google-chart {width:809px; height:500px;} 19 | -------------------------------------------------------------------------------- /sh/pgedb360_database_configuration.sh: -------------------------------------------------------------------------------- 1 | ## Queries By Abel Macias and contributions. 2 | 3 | title='All visible tables, views, sequences and foreign tables' 4 | sql_text='\d' 5 | output_type='text' 6 | fc_exec_item 7 | 8 | title='Lists tablespaces' 9 | sql_text='\db+' 10 | output_type='text' 11 | fc_exec_item 12 | 13 | # https://github.com/lesovsky/zabbix-extensions/issues/42 14 | # select * from pg_ls_dir('pg_xlog'); 15 | # Abel Macias 16 | # \! ls -l $PGDATA/pg_xlog 17 | title='List of xlogs' 18 | sql_text=$(cat <<'END_HEREDOC' 19 | select d.xlog_dir||'/'||f.xlogfile xlogfile , pg_stat_file(d.xlog_dir||'/'||f.xlogfile) file_info 20 | from (select substr(sourcefile,1,position('/data/' in sourcefile)+5)||'pg_xlog' xlog_dir 21 | from pg_file_settings 22 | limit 1 23 | ) as d, 24 | (select pg_ls_dir('pg_xlog') as xlogfile) as f 25 | ORDER BY file_info 26 | END_HEREDOC 27 | ) 28 | fc_exec_item 29 | 30 | # postgresqltuner.pl 31 | title='Tablespaces' 32 | main_table='pg_tablespace' 33 | sql_text=$(cat <<'END_HEREDOC' 34 | select spcname,pg_tablespace_location(oid) 35 | from pg_tablespace 36 | where pg_tablespace_location(oid) like current_setting('data_directory')||'/%' 37 | END_HEREDOC 38 | ) 39 | fc_exec_item 40 | 41 | title='Lists installed extensions' 42 | sql_text='\dx+' 43 | 44 | title='Settings' 45 | main_table='pg_settings' 46 | sql_text=$(cat <<'END_HEREDOC' 47 | select (case when boot_val is not null and setting<>boot_val then '*' END) not_default, 48 | name,unit,setting,boot_val,reset_val 49 | from pg_settings 50 | order by not_default,name 51 | END_HEREDOC 52 | ) 53 | fc_exec_item -------------------------------------------------------------------------------- /sh/pgedb360_checkpoints.sh: -------------------------------------------------------------------------------- 1 | ## Queries By Abel Macias and contributions. 2 | 3 | # PG 9.0 Hiperf book 4 | title='Checkpoint efficiency' 5 | sql_text=$(cat <<'END_HEREDOC' 6 | SELECT current_setting('bgwriter_lru_maxpages') as bgwriter_lru_maxpages, 7 | current_setting('bgwriter_lru_multiplier') as bgwriter_lru_multiplier, 8 | current_setting('checkpoint_timeout') as checkpoint_timeout, 9 | current_setting('checkpoint_completion_target') AS checkpoint_completion_target, 10 | current_setting('max_wal_size') as max_wal_size, 11 | current_setting('shared_buffers') as shared_buffers 12 | END_HEREDOC 13 | ) 14 | fc_exec_item 15 | 16 | title='Checkpoints' 17 | sql_text=$(cat <<'END_HEREDOC' 18 | SELECT 19 | (checkpoints_timed+checkpoints_req) AS "total checkpoints", 20 | EXTRACT(EPOCH FROM (now() - stats_reset)) / (checkpoints_timed+checkpoints_req)/ 60 AS "minutes between checkpoints", 21 | 60*1000/cast(trim('ms' from current_setting('bgwriter_delay')) as integer) AS "bgwriter writes per minute", 22 | round(100 * checkpoints_timed / (checkpoints_timed + checkpoints_req),2) ||' / '|| 23 | round(100 * checkpoints_req / (checkpoints_timed + checkpoints_req),2) AS "checkpoints timed/requested pct", 24 | round(100 * buffers_checkpoint / (buffers_checkpoint + buffers_clean + buffers_backend),2) ||' / '|| 25 | round(100 * buffers_clean / (buffers_checkpoint + buffers_clean + buffers_backend),2) ||' / '|| 26 | round(100 * buffers_backend / (buffers_checkpoint + buffers_clean + buffers_backend),2) AS "buffers clean by (checkpoint / bgwrt / backend) pct", 27 | pg_size_pretty(buffers_checkpoint * block_size / (checkpoints_timed + checkpoints_req)) AS "average checkpoint write bytes", 28 | pg_size_pretty(block_size * (buffers_checkpoint + buffers_clean + buffers_backend)) AS "total bytes written", 29 | now()-stats_reset "time since stats reset", 30 | stats_reset "stats reset timestamp" 31 | FROM pg_stat_bgwriter, 32 | (select cast(current_setting('block_size') AS integer) AS block_size, 33 | cast(trim('ms' from current_setting('bgwriter_delay')) as integer) AS bgwriter_delay 34 | ) AS p 35 | END_HEREDOC 36 | ) 37 | fc_exec_item -------------------------------------------------------------------------------- /moat370/js/decode.min.js: -------------------------------------------------------------------------------- 1 | function get_password(){var e=prompt("Please enter password","");if(null!=e&&""!=e)return e}function get_param(e,t){t||(t=location.href),e=e.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var n=new RegExp("[\\?&]"+e+"=([^&#]*)").exec(t);return null==n?null:n[1]}function decompText(t){try{var e=atob(t).split("").map(function(e){return e.charCodeAt(0)}),n=new Uint8Array(e),r=new Zlib.Gunzip(n).decompress();return new TextDecoder("utf-8").decode(r)}catch(e){return t}}function rjorge_decrypt(e,t){e||(e=get_password());var n="";if(null!=e&&""!=e&&(n=CryptoJS.AES.decrypt(enctext,e)),null!=n&&""!=n){try{var r=n.toString(CryptoJS.enc.Utf8)}catch(e){return void(t||alert("Wrong Passphrase"))}if(enctext_comp)var o=decompText(r);else o=r;!t&&isIndexPage()?setParamCurURL("decKey",e):(loadHTML(o),appendPassURL("decKey",e))}}function rjorge_decomp(){loadHTML(decompText(enctext))}function loadHTML(e){document.getElementById("rjorge_block").innerHTML=e,reload_script_section("sqlfor_script"),reload_script_section("sqlhl_script"),loadJS("tablefilter/tablefilter.js",function(){reload_script_section("tablefilter-cfg")}),loadJS("d3.min.js",function(){reload_script_section("d3_script")}),loadJS("http://www.gstatic.com/charts/loader.js",function(){reload_script_section("gchart_script")})}function reload_script_section(name){var reload_script_sec_name=document.getElementById(name);null!=reload_script_sec_name&&""!=reload_script_sec_name&&eval(reload_script_sec_name.text)}function isIndexPage(){return!!window.location.pathname.match(/00001_.*_index.html$/)}function appendPassURL(e,t){for(var n=document.getElementsByTagName("a"),r=0;r 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | #************************************************************************ 19 | 20 | ######################## 21 | # Mandatory Functions: # 22 | ######################## 23 | 24 | # fc_db_startup_connection 25 | # fc_db_end_connection 26 | # fc_db_check_connection 27 | # fc_db_begin_code 28 | # fc_db_end_code 29 | # fc_db_run_file 30 | # fc_db_define_module 31 | # fc_db_reset_options 32 | # fc_db_pre_section_call 33 | # fc_db_create_csv 34 | # fc_db_table_description 35 | # fc_db_check_file_sql_error 36 | # fc_db_enable_trace 37 | # fc_db_pre_exec_call 38 | # fc_db_sql_transform 39 | 40 | ######################## 41 | 42 | fc_db_startup_connection () 43 | { 44 | true 45 | } 46 | 47 | fc_db_end_connection () 48 | { 49 | true 50 | } 51 | 52 | fc_db_check_connection () 53 | { 54 | true 55 | } 56 | 57 | fc_db_begin_code () 58 | { 59 | hosts_count=1 60 | avg_core_count=1 61 | avg_thread_count=1 62 | database_name=db 63 | host_name=host 64 | db_version=v1 65 | } 66 | 67 | fc_db_end_code () 68 | { 69 | true 70 | } 71 | 72 | fc_db_run_file () 73 | { 74 | true 75 | } 76 | 77 | fc_db_define_module () 78 | { 79 | true 80 | } 81 | 82 | fc_db_reset_options () 83 | { 84 | true 85 | } 86 | 87 | fc_db_pre_section_call () 88 | { 89 | true 90 | } 91 | 92 | fc_db_create_csv () 93 | { 94 | true 95 | } 96 | 97 | fc_db_table_description () 98 | { 99 | true 100 | } 101 | 102 | fc_db_check_file_sql_error () 103 | { 104 | true 105 | } 106 | 107 | fc_db_enable_trace () 108 | { 109 | true 110 | } 111 | 112 | fc_db_pre_exec_call () 113 | { 114 | true 115 | } 116 | 117 | fc_db_sql_transform () 118 | { 119 | true 120 | } -------------------------------------------------------------------------------- /moat370/sh/moat370_0c_post.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #************************************************************************ 3 | # 4 | # Copyright 2021 Rodrigo Jorge 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License" 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES -o CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | #************************************************************************ 19 | 20 | ## End Time 21 | moat370_main_time1=$(get_secs) 22 | 23 | total_hours="Tool execution time: $(convert_secs $(do_calc 'moat370_main_time1-moat370_main_time0'))." 24 | 25 | moat370_time_stamp=$(date "${moat370_date_format}") 26 | fc_paste_file_replacing_variables "${moat370_fdr_cfg}"/moat370_html_footer.html "${moat370_main_report}" 27 | 28 | fc_encode_html "${moat370_main_report}" 'INDEX' 29 | 30 | ## Readme 31 | echo "1. Unzip ${moat370_zip_filename_nopath} into a directory" > "${moat370_readme}" 32 | echo "2. Review ${moat370_main_report_nopath}" >> "${moat370_readme}" 33 | 34 | ## encrypt final files 35 | ## fc_convert_txt_to_html ${moat370_log} 36 | ## fc_encode_html ${moat370_log} 37 | ## fc_convert_txt_to_html ${moat370_log2} 38 | ## fc_encode_html ${moat370_log2} 39 | 40 | ## Zip 41 | fc_def_empty_var moat370_d3_usage 42 | if [ "${moat370_d3_usage}" = 'Y' ] 43 | then 44 | fc_zip_file "${moat370_zip_filename}" "${moat370_fdr_js}/d3.min.js" false 45 | fi 46 | 47 | fc_clean_file_name "moat370_log3" "moat370_log3_nopath" "PATH" 48 | 49 | fc_def_empty_var moat370_tf_usage 50 | if [ "${moat370_tf_usage}" = 'Y' ] 51 | then 52 | v_zipfdr=$(dirname "${moat370_zip_filename}") 53 | cp -av ${moat370_fdr_js}/tablefilter "${moat370_sw_output_fdr}/" >> "${moat370_log3}" 54 | cd "${moat370_sw_output_fdr}/" 55 | zip -rm $(cd - >/dev/null; cd "${v_zipfdr}"; pwd)/${moat370_zip_filename_nopath} tablefilter/ >> "${moat370_log3_nopath}" 56 | cd - >/dev/null 57 | fi 58 | ## Fix above cmd as cur folder can be RO 59 | 60 | if [ -z "${moat370_pre_sw_key_file}" ] 61 | then 62 | rm -f "${enc_key_file}" 63 | fi 64 | 65 | # Disconnect 66 | fc_db_end_connection 67 | 68 | fc_zip_file "${moat370_zip_filename}" "${moat370_driver}" 69 | fc_zip_file "${moat370_zip_filename}" "${moat370_log2}" 70 | fc_zip_file "${moat370_zip_filename}" "${moat370_log}" 71 | fc_zip_file "${moat370_zip_filename}" "${moat370_main_report}" 72 | fc_zip_file "${moat370_zip_filename}" "${moat370_readme}" 73 | 74 | unzip -l "${moat370_zip_filename}" >> "${moat370_log3}" 75 | zip -mj "${moat370_zip_filename}" "${moat370_log3}" > /dev/null -------------------------------------------------------------------------------- /moat370/database/oracle/oracle_pre.sql: -------------------------------------------------------------------------------- 1 | -- ENABLE ALL ROLES FOR USER 2 | SET ROLE ALL; 3 | 4 | -- NLS 5 | ALTER SESSION SET NLS_NUMERIC_CHARACTERS=".,"; 6 | ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD/HH24:MI:SS'; 7 | ALTER SESSION SET NLS_TIMESTAMP_FORMAT='YYYY-MM-DD/HH24:MI:SS.FF'; 8 | ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD/HH24:MI:SS.FF TZH:TZM'; 9 | 10 | -- get average number of CPUs 11 | COL avg_cpu_count NEW_V avg_cpu_count FOR A6 12 | SELECT TO_CHAR(ROUND(AVG(TO_NUMBER(value)),1)) avg_cpu_count FROM gv$system_parameter2 WHERE name='cpu_count'; 13 | COL avg_cpu_count clear 14 | 15 | -- get total number of CPUs 16 | COL sum_cpu_count NEW_V sum_cpu_count FOR A3 17 | SELECT TO_CHAR(SUM(TO_NUMBER(value))) sum_cpu_count FROM gv$system_parameter2 WHERE name='cpu_count'; 18 | COL sum_cpu_count clear 19 | 20 | -- get average number of Cores 21 | COL avg_core_count NEW_V avg_core_count FOR A5 22 | SELECT TO_CHAR(ROUND(AVG(TO_NUMBER(value)),1)) avg_core_count FROM gv$osstat WHERE stat_name='NUM_CPU_CORES'; 23 | COL avg_core_count clear 24 | 25 | -- get average number of Threads 26 | COL avg_thread_count NEW_V avg_thread_count FOR A6 27 | SELECT TO_CHAR(ROUND(AVG(TO_NUMBER(value)),1)) avg_thread_count FROM gv$osstat WHERE stat_name='NUM_CPUS'; 28 | COL avg_thread_count clear 29 | 30 | -- get number of Hosts 31 | COL hosts_count NEW_V hosts_count FOR A2 32 | SELECT TO_CHAR(COUNT(DISTINCT inst_id)) hosts_count FROM gv$osstat WHERE stat_name='NUM_CPU_CORES'; 33 | COL hosts_count clear 34 | 35 | -- get udump directory path 36 | COL moat370_udump_path NEW_V moat370_udump_path FOR A500 37 | -- CHR(92)=\ 38 | SELECT value||DECODE(INSTR(value, '/'), 0, CHR(92), '/') moat370_udump_path FROM v$parameter2 WHERE name='user_dump_dest'; 39 | SELECT value||DECODE(INSTR(value, '/'), 0, CHR(92), '/') moat370_udump_path FROM v$diag_info WHERE name='Diag Trace'; 40 | COL moat370_udump_path clear 41 | 42 | -- get background directory path 43 | COL background_dump_dest NEW_V background_dump_dest 44 | SELECT value background_dump_dest FROM v$parameter WHERE name = 'background_dump_dest'; 45 | COL background_dump_dest clear 46 | 47 | -- get pid 48 | COL moat370_spid NEW_V moat370_spid FOR A5 49 | SELECT TO_CHAR(spid) moat370_spid FROM v$session s, v$process p 50 | WHERE s.sid=SYS_CONTEXT('USERENV', 'SID') AND p.addr=s.paddr; 51 | COL moat370_spid clear 52 | 53 | -- get database name (up to 10, stop before first '.', no special characters) 54 | COL database_name NEW_V database_name 55 | SELECT SYS_CONTEXT('USERENV', 'DB_NAME') database_name FROM DUAL; 56 | COL database_name clear 57 | 58 | -- get host name (up to 30, stop before first '.', no special characters) 59 | COL host_name NEW_V host_name 60 | SELECT SYS_CONTEXT('USERENV', 'SERVER_HOST') host_name FROM DUAL; 61 | COL host_name clear 62 | 63 | -- get rdbms version 64 | COL db_version NEW_V db_version 65 | SELECT version db_version FROM v$instance; 66 | COL db_version clear 67 | 68 | COL moat370_prev_sql_id NEW_V moat370_prev_sql_id NOPRI 69 | COL moat370_prev_child_number NEW_V moat370_prev_child_number NOPRI -------------------------------------------------------------------------------- /sh/pgedb360_replica.sh: -------------------------------------------------------------------------------- 1 | ## Queries By Abel Macias and contributions. 2 | 3 | title='Replica Settings' 4 | main_table='pg_settings' 5 | sql_text=$(cat <<'END_HEREDOC' 6 | select (case when boot_val is not null and setting<>boot_val then '*' END) not_default, 7 | name,unit,setting,boot_val,reset_val 8 | from pg_settings 9 | where name in ('huge_pages','shared_buffers','work_mem','archive_mode', 10 | 'hot_standby','max_replication_slots','prepared transactions', 11 | 'track_commit_timestamp') 12 | or name like '%wal%' 13 | order by not_default,name 14 | END_HEREDOC 15 | ) 16 | fc_exec_item 17 | 18 | title='Replication Status' 19 | main_table='pg_replication_slots' 20 | sql_text=$(cat <<'END_HEREDOC' 21 | SELECT slot_name, 22 | pg_wal_lsn_diff(pg_current_wal_lsn(),restart_lsn) as restart_lag, 23 | pg_wal_lsn_diff(pg_current_wal_lsn(),confirmed_flush_lsn) as flush_lag 24 | FROM pg_replication_slots ORDER BY slot_name 25 | END_HEREDOC 26 | ) 27 | fc_exec_item 28 | 29 | title='Replication Slots' 30 | main_table='pg_replication_slots' 31 | sql_text=$(cat <<'END_HEREDOC' 32 | select * 33 | FROM pg_replication_slots ORDER BY slot_name 34 | END_HEREDOC 35 | ) 36 | fc_exec_item 37 | 38 | title='Replication Origins' 39 | main_table='pg_replication_origin' 40 | sql_text='SELECT * FROM pg_replication_origin ORDER BY roname' 41 | fc_exec_item 42 | 43 | title='Replication Origin Status' 44 | main_table='pg_replication_origin_status' 45 | sql_text='SELECT * FROM pg_replication_origin_status order by external_id' 46 | fc_exec_item 47 | 48 | title='Objects with replica setting' 49 | main_table='pg_class' 50 | sql_text=$(cat <<'END_HEREDOC' 51 | select * 52 | from pg_class c 53 | where (select v[1] FROM regexp_matches(reloptions::text,E'Replica') as r(v) limit 1) IS NOT NULL 54 | ORDER BY relname 55 | END_HEREDOC 56 | ) 57 | fc_exec_item 58 | 59 | ## https://blog.2ndquadrant.com/pg-phriday-terrific-throughput-tracking/ 60 | title='Replication Lags' 61 | main_table='pg_stat_replication' 62 | sql_text=$(cat <<'END_HEREDOC' 63 | SELECT client_addr, 64 | pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag, 65 | pg_wal_lsn_diff(pg_current_wal_lsn(),write_lsn) AS write_lag, 66 | pg_wal_lsn_diff(pg_current_wal_lsn(),flush_lsn) AS flush_lag, 67 | pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS replay_lag, 68 | * 69 | FROM pg_stat_replication order by pg_stat_replication desc 70 | END_HEREDOC 71 | ) 72 | fc_exec_item 73 | 74 | title='Subscriptions' 75 | main_table='pg_stat_subscription' 76 | sql_text='select * from pg_stat_subscription order by subname' 77 | fc_exec_item 78 | 79 | ## https://github.com/lesovsky/zabbix-extensions/issues/42 80 | ## select * from pg_ls_dir('pg_xlog'); 81 | ## Abel Macias 82 | ## \! ls -l $PGDATA/pg_xlog 83 | 84 | title='List of xlogs' 85 | main_table='pg_file_settings' 86 | sql_text=$(cat <<'END_HEREDOC' 87 | select d.xlog_dir||'/'||f.xlogfile xlogfile , pg_stat_file(d.xlog_dir||'/'||f.xlogfile) file_info 88 | from (select substr(sourcefile,1,position('/data/' in sourcefile)+5)||'pg_xlog' xlog_dir 89 | from pg_file_settings 90 | limit 1 91 | ) as d, 92 | (select pg_ls_dir('pg_xlog') as xlogfile) as f 93 | ORDER BY file_info 94 | END_HEREDOC 95 | ) 96 | fc_exec_item 97 | -------------------------------------------------------------------------------- /sh/pgedb360_sessions.sh: -------------------------------------------------------------------------------- 1 | ## Queries By Abel Macias and contributions. 2 | 3 | sql_text_bkp=$(cat <<'END_HEREDOC' 4 | select wait_event, state, count(1) as Num, 5 | min(backend_start) as oldest_backend_start, 6 | min(xact_start) as oldest_xact_start, 7 | min(query_start) as oldest_query_start, 8 | min(state_change) as oldest_state_change 9 | from pg_stat_activity 10 | where datname=current_database() 11 | and state not in ('active','fastpath function call') 12 | group by wait_event, state 13 | END_HEREDOC 14 | ) 15 | 16 | title='Session - Snap 1' 17 | main_table='pg_stat_activity' 18 | sql_text=${sql_text_bkp} 19 | fc_exec_item 20 | 21 | sleep 10 22 | 23 | title='Session - Snap 2' 24 | main_table='pg_stat_activity' 25 | sql_text=${sql_text_bkp} 26 | fc_exec_item 27 | 28 | sleep 10 29 | 30 | title='Session - Snap 3' 31 | main_table='pg_stat_activity' 32 | sql_text=${sql_text_bkp} 33 | fc_exec_item 34 | 35 | sleep 10 36 | 37 | title='Session - Snap 4' 38 | main_table='pg_stat_activity' 39 | sql_text=${sql_text_bkp} 40 | fc_exec_item 41 | 42 | sleep 10 43 | 44 | title='Session - Snap 5' 45 | main_table='pg_stat_activity' 46 | sql_text=${sql_text_bkp} 47 | fc_exec_item 48 | 49 | sleep 10 50 | 51 | title='Session - Snap 6' 52 | main_table='pg_stat_activity' 53 | sql_text=${sql_text_bkp} 54 | fc_exec_item 55 | 56 | sleep 10 57 | 58 | title='Session - Snap 7' 59 | main_table='pg_stat_activity' 60 | sql_text=${sql_text_bkp} 61 | fc_exec_item 62 | 63 | sleep 10 64 | 65 | title='Session - Snap 8' 66 | main_table='pg_stat_activity' 67 | sql_text=${sql_text_bkp} 68 | fc_exec_item 69 | 70 | ############################################# 71 | ############################################# 72 | ############################################# 73 | 74 | sql_text_bkp=$(cat <<'END_HEREDOC' 75 | select state,count(1) as Num, 76 | min(backend_start) as oldest_backend_start, 77 | min(xact_start) as oldest_xact_start, 78 | min(query_start) as oldest_query_start, 79 | min(state_change) as oldest_state_change 80 | from pg_stat_activity 81 | where datname=current_database() 82 | group by state 83 | order by state 84 | END_HEREDOC 85 | ) 86 | 87 | title='Session - Snap 1' 88 | main_table='pg_stat_activity' 89 | sql_text=${sql_text_bkp} 90 | fc_exec_item 91 | 92 | sleep 10 93 | 94 | title='Session - Snap 2' 95 | main_table='pg_stat_activity' 96 | sql_text=${sql_text_bkp} 97 | fc_exec_item 98 | 99 | sleep 10 100 | 101 | title='Session - Snap 3' 102 | main_table='pg_stat_activity' 103 | sql_text=${sql_text_bkp} 104 | fc_exec_item 105 | 106 | sleep 10 107 | 108 | title='Session - Snap 4' 109 | main_table='pg_stat_activity' 110 | sql_text=${sql_text_bkp} 111 | fc_exec_item 112 | 113 | sleep 10 114 | 115 | title='Session - Snap 5' 116 | main_table='pg_stat_activity' 117 | sql_text=${sql_text_bkp} 118 | fc_exec_item 119 | 120 | sleep 10 121 | 122 | title='Session - Snap 6' 123 | main_table='pg_stat_activity' 124 | sql_text=${sql_text_bkp} 125 | fc_exec_item 126 | 127 | sleep 10 128 | 129 | title='Session - Snap 7' 130 | main_table='pg_stat_activity' 131 | sql_text=${sql_text_bkp} 132 | fc_exec_item 133 | 134 | sleep 10 135 | 136 | title='Session - Snap 8' 137 | main_table='pg_stat_activity' 138 | sql_text=${sql_text_bkp} 139 | fc_exec_item 140 | 141 | unset sql_text_bkp -------------------------------------------------------------------------------- /sh/pgedb360_database_state.sh: -------------------------------------------------------------------------------- 1 | ## Queries By Abel Macias and contributions. 2 | 3 | title='Cluster' 4 | sql_text='SELECT datname as "databases in this cluster" FROM pg_database WHERE NOT datistemplate AND datallowconn' 5 | fc_exec_item 6 | 7 | title='Version' 8 | sql_text='select version()' 9 | fc_exec_item 10 | 11 | title='Uptime' 12 | sql_text='select current_database(),pg_postmaster_start_time(),now()-pg_postmaster_start_time() as "Uptime"' 13 | fc_exec_item 14 | 15 | title='Database Info' 16 | main_table='pg_settings' 17 | sql_text=$(cat <<'END_HEREDOC' 18 | select min(case name when 'huge_pages' then setting end) as "Huge Pages", 19 | min(case name when 'shared_buffers' then setting||' '||unit end) as "Shared Buffers", 20 | min(case name when 'work_mem' then setting||' '||unit end) as "Work Memory", 21 | min(case name when 'wal_buffers' then setting||' '||unit end) as "WAL Buffers", 22 | min(case name when 'max_wal_size' then setting||' '||unit end) as "Max WAL Size", 23 | min(case name when 'archive_mode' then setting end) as "Archive Mode", 24 | min(case name when 'hot_standby' then setting end) as "Hot Standby", 25 | min(case name when 'password_encryption' then setting END) as "Password Encryption", 26 | min(case name when 'prepared transactions' then setting end) as "Prepared Transactions" 27 | from (select name,setting,unit from pg_settings 28 | union 29 | select 'prepared transactions',count(1)::text,' ' from pg_prepared_xacts) p 30 | END_HEREDOC 31 | ) 32 | fc_exec_item 33 | 34 | title='Connections' 35 | main_table='pg_stat_activity' 36 | sql_text=$(cat <<'END_HEREDOC' 37 | select a.current_connections , 38 | p.superuser_connections as "allowed superuser connections", 39 | round(100*a.current_connections/p.max_connections)::text||'%' as "connection saturation", 40 | a.oldest_connection, 41 | a.avg_connection_age, 42 | a.oldest_transaction 43 | from (select count(1) as current_connections, 44 | max(now()-backend_start) as oldest_connection, 45 | avg(now()-backend_start) as avg_connection_age, 46 | max(now()-xact_start) as oldest_transaction 47 | from pg_stat_activity) a, 48 | (select current_setting('max_connections')::integer as max_connections, 49 | current_setting('superuser_reserved_connections') as superuser_connections 50 | ) p 51 | END_HEREDOC 52 | ) 53 | fc_exec_item 54 | 55 | title='Autovacuum' 56 | main_table='pg_settings' 57 | sql_text=$(cat <<'END_HEREDOC' 58 | select autovacuum,autovacuum_max_workers, 59 | (case maintenance_work_mem when -1 then work_mem else maintenance_work_mem end)*autovacuum_max_workers autovacuum_max_memory_kb 60 | from (select min(case name when 'max_connections' then setting::integer end) as max_connections, 61 | min(case name when 'work_mem' then setting::integer end) as work_mem, 62 | min(case name when 'maintenance_work_mem' then setting::integer end) as maintenance_work_mem, 63 | min(case name when 'autovacuum_max_workers' then setting::integer end) as autovacuum_max_workers, 64 | min(case name when 'autovacuum' then setting end) as autovacuum 65 | from pg_settings 66 | ) p 67 | END_HEREDOC 68 | ) 69 | fc_exec_item 70 | 71 | title='Stat Database' 72 | main_table='pg_stat_database' 73 | sql_text='select * from pg_stat_database' 74 | fc_exec_item 75 | 76 | 77 | -------------------------------------------------------------------------------- /sh/pgedb360_buffer_cache.sh: -------------------------------------------------------------------------------- 1 | ## Queries By Abel Macias and contributions. 2 | 3 | ############################## 4 | # fc_load_variable converts a database variable into a shellscript variable. 5 | fc_load_variable pgedb360_pg_buffercache 6 | ############################## 7 | 8 | title='Cache Hit Ratio' 9 | main_table='pg_stat_database' 10 | sql_text='select sum(blks_hit)*100/sum(blks_hit+blks_read) as "Global Cache Hit Ratio" 11 | from pg_stat_database' 12 | fc_exec_item 13 | 14 | # PG 9.0 HiPerf book 15 | title='Cache hit ratio per table' 16 | main_table='pg_statio_user_tables' 17 | sql_text=$(cat <<'END_HEREDOC' 18 | with dat as 19 | (select schemaname,relname as tablename, 20 | coalesce(heap_blks_hit ,0) heap_blks_hit, 21 | coalesce(heap_blks_read ,0) heap_blks_read, 22 | coalesce(toast_blks_hit ,0) toast_blks_hit, 23 | coalesce(toast_blks_read,0) toast_blks_read, 24 | coalesce(idx_blks_hit ,0) idx_blks_hit, 25 | coalesce(idx_blks_read ,0) idx_blks_read 26 | FROM pg_statio_user_tables 27 | ) 28 | SELECT 29 | round(100*cast(heap_blks_hit as numeric) / (heap_blks_hit + heap_blks_read+0.0001) ,2) AS hit_pct, 30 | round(100*cast(toast_blks_hit as numeric) / (toast_blks_hit+toast_blks_read+0.0001) ,2) AS toast_hit_pct, 31 | round(100*cast(idx_blks_hit as numeric) / (idx_blks_hit + idx_blks_read+0.0001) ,2) AS idx_hit_pct, 32 | * 33 | FROM dat 34 | WHERE heap_blks_hit>0 OR heap_blks_read>0 OR idx_blks_read>0 35 | ORDER BY (case when (heap_blks_read+toast_blks_read+idx_blks_read)>2^30 then 1 36 | when (heap_blks_read+toast_blks_read+idx_blks_read)>2^25 then 2 37 | when (heap_blks_read+toast_blks_read+idx_blks_read)>2^20 then 3 38 | else 4 end 39 | ),hit_pct 40 | END_HEREDOC 41 | ) 42 | fc_exec_item 43 | 44 | ### PG 9.0 HiPerf book 45 | ### Accesing pg_buffercache may cause performance impact 46 | title='Relative to the buffer cache and its total size' 47 | footer='How much data is being cached for each table' 48 | main_table='pg_statio_user_tables' 49 | sql_text=$(cat <<'END_HEREDOC' 50 | SELECT 51 | t.schemaname,c.relname as tablename, 52 | pg_size_pretty(count(*) * 8192) as buffered, 53 | round(100.0 * count(*) / 54 | (SELECT setting FROM pg_settings WHERE name='shared_buffers')::integer,2) AS "% of buffers", 55 | round(100.0 * count(*) * 8192 / pg_table_size(c.oid),2) AS "% of table", 56 | round(100.0*sum(case when isdirty then 1 else 0 end) / count(*),2) as "% dirty" 57 | FROM pg_class c 58 | INNER JOIN pg_buffercache b 59 | ON b.relfilenode = c.relfilenode 60 | INNER JOIN pg_database d 61 | ON (b.reldatabase = d.oid AND d.datname = current_database()) 62 | INNER JOIN pg_statio_user_tables t 63 | on (c.oid=t.relid) 64 | GROUP BY t.schemaname,c.oid,c.relname 65 | ORDER BY 3 DESC 66 | LIMIT 25 67 | END_HEREDOC 68 | ) 69 | [ ${pgedb360_pg_buffercache} -gt 0 ] && fc_exec_item 70 | footer='' 71 | 72 | ### PG 9.0 HiPerf book 73 | ### Decrease buffer cache if few blocks have high usage count. increase if most blocks have high usage count. 74 | ### Accesing pg_buffercache may cause performance impact 75 | 76 | title='Histogram of objects pages usagecount' 77 | main_table='pg_statio_user_tables' 78 | sql_text=$(cat <<'END_HEREDOC' 79 | SELECT t.schemaname, c.relname, count(*) AS buffers,usagecount 80 | FROM pg_class c 81 | INNER JOIN pg_buffercache b 82 | ON b.relfilenode = c.relfilenode 83 | INNER JOIN pg_database d 84 | ON (b.reldatabase = d.oid AND d.datname = current_database()) 85 | INNER JOIN pg_statio_user_tables t 86 | on (c.oid=t.relid) 87 | GROUP BY t.schemaname,c.relname,usagecount 88 | ORDER BY c.relname,usagecount 89 | END_HEREDOC 90 | ) 91 | [ ${pgedb360_pg_buffercache} -gt 0 ] && fc_exec_item -------------------------------------------------------------------------------- /sh/pgedb360_locks.sh: -------------------------------------------------------------------------------- 1 | ## Queries By Abel Macias and contributions. 2 | 3 | ## https://blog.dataegret.com/2017/10/deep-dive-into-postgres-stats.html 4 | 5 | title='Locks' 6 | sql_text=$(cat <<'END_HEREDOC' 7 | WITH RECURSIVE l AS ( 8 | SELECT pid, locktype, mode, granted, 9 | ROW(locktype,database,relation,page,tuple,virtualxid,transactionid,classid,objid,objsubid) obj 10 | FROM pg_locks 11 | ), pairs AS ( 12 | SELECT w.pid waiter, l.pid locker, l.obj, l.mode 13 | FROM l w 14 | JOIN l ON l.obj IS NOT DISTINCT FROM w.obj AND l.locktype=w.locktype AND NOT l.pid=w.pid AND l.granted 15 | WHERE NOT w.granted 16 | ), tree AS ( 17 | SELECT l.locker pid, l.locker root, NULL::record obj, NULL AS mode, 0 lvl, locker::text path, array_agg(l.locker) OVER () all_pids 18 | FROM ( SELECT DISTINCT locker FROM pairs l WHERE NOT EXISTS (SELECT 1 FROM pairs WHERE waiter=l.locker) ) l 19 | UNION ALL 20 | SELECT w.waiter pid, tree.root, w.obj, w.mode, tree.lvl+1, tree.path||'.'||w.waiter, all_pids || array_agg(w.waiter) OVER () 21 | FROM tree JOIN pairs w ON tree.pid=w.locker AND NOT w.waiter = ANY ( all_pids ) 22 | ) 23 | SELECT (clock_timestamp() - a.xact_start)::interval(3) AS ts_age, 24 | replace(a.state, 'idle in transaction', 'idletx') state, 25 | (clock_timestamp() - state_change)::interval(3) AS change_age, 26 | a.datname,tree.pid,a.usename,a.client_addr,lvl, 27 | (SELECT count(*) FROM tree p WHERE p.path ~ ('^'||tree.path) AND NOT p.path=tree.path) blocked, 28 | repeat(' .', lvl)||' '||left(regexp_replace(query, '\s+', ' ', 'g'),100) query 29 | FROM tree 30 | JOIN pg_stat_activity a USING (pid) 31 | ORDER BY path 32 | END_HEREDOC 33 | ) 34 | fc_exec_item 35 | 36 | ### https://severalnines.com/blog/why-postgresql-running-slow-tips-tricks-get-source 37 | title='Blocker and blocked sessions and DML' 38 | sql_text=$(cat <<'END_HEREDOC' 39 | SELECT blocked_locks.pid AS blocked_pid, 40 | blocked_activity.usename AS blocked_user, 41 | blocking_locks.pid AS blocking_pid, 42 | blocking_activity.usename AS blocking_user, 43 | blocked_activity.query AS blocked_statement, 44 | blocking_activity.query AS current_statement_in_blocking_process 45 | FROM pg_catalog.pg_locks blocked_locks 46 | JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid 47 | JOIN pg_catalog.pg_locks blocking_locks 48 | ON blocking_locks.locktype = blocked_locks.locktype 49 | AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE 50 | AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation 51 | AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page 52 | AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple 53 | AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid 54 | AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid 55 | AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid 56 | AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid 57 | AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid 58 | AND blocking_locks.pid != blocked_locks.pid 59 | JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid 60 | WHERE NOT blocked_locks.GRANTED 61 | END_HEREDOC 62 | ) 63 | fc_exec_item 64 | 65 | ### https://www.postgresql.org/docs/9.1/monitoring-stats.html 66 | title='How many deadlocks and other conflict have happened' 67 | sql_text=$(cat <<'END_HEREDOC' 68 | select * from pg_stat_database_conflicts 69 | where datname = current_database() 70 | END_HEREDOC 71 | ) 72 | fc_exec_item 73 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 11 | build. 12 | 2. Update the README.md with details of changes to the interface, this includes new environment 13 | variables, exposed ports, useful file locations and container parameters. 14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this 15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 17 | do not have permission to do that, you may request the second reviewer to merge it for you. 18 | 19 | ## Code of Conduct 20 | 21 | ### Our Pledge 22 | 23 | In the interest of fostering an open and welcoming environment, we as 24 | contributors and maintainers pledge to making participation in our project and 25 | our community a harassment-free experience for everyone, regardless of age, body 26 | size, disability, ethnicity, gender identity and expression, level of experience, 27 | nationality, personal appearance, race, religion, or sexual identity and 28 | orientation. 29 | 30 | ### Our Standards 31 | 32 | Examples of behavior that contributes to creating a positive environment 33 | include: 34 | 35 | * Using welcoming and inclusive language 36 | * Being respectful of differing viewpoints and experiences 37 | * Gracefully accepting constructive criticism 38 | * Focusing on what is best for the community 39 | * Showing empathy towards other community members 40 | 41 | Examples of unacceptable behavior by participants include: 42 | 43 | * The use of sexualized language or imagery and unwelcome sexual attention or 44 | advances 45 | * Trolling, insulting/derogatory comments, and personal or political attacks 46 | * Public or private harassment 47 | * Publishing others' private information, such as a physical or electronic 48 | address, without explicit permission 49 | * Other conduct which could reasonably be considered inappropriate in a 50 | professional setting 51 | 52 | ### Our Responsibilities 53 | 54 | Project maintainers are responsible for clarifying the standards of acceptable 55 | behavior and are expected to take appropriate and fair corrective action in 56 | response to any instances of unacceptable behavior. 57 | 58 | Project maintainers have the right and responsibility to remove, edit, or 59 | reject comments, commits, code, wiki edits, issues, and other contributions 60 | that are not aligned to this Code of Conduct, or to ban temporarily or 61 | permanently any contributor for other behaviors that they deem inappropriate, 62 | threatening, offensive, or harmful. 63 | 64 | ### Scope 65 | 66 | This Code of Conduct applies both within project spaces and in public spaces 67 | when an individual is representing the project or its community. Examples of 68 | representing a project or community include using an official project e-mail 69 | address, posting via an official social media account, or acting as an appointed 70 | representative at an online or offline event. Representation of a project may be 71 | further defined and clarified by project maintainers. 72 | 73 | ### Enforcement 74 | 75 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 76 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All 77 | complaints will be reviewed and investigated and will result in a response that 78 | is deemed necessary and appropriate to the circumstances. The project team is 79 | obligated to maintain confidentiality with regard to the reporter of an incident. 80 | Further details of specific enforcement policies may be posted separately. 81 | 82 | Project maintainers who do not follow or enforce the Code of Conduct in good 83 | faith may face temporary or permanent repercussions as determined by other 84 | members of the project's leadership. 85 | 86 | ### Attribution 87 | 88 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 89 | available at [http://contributor-covenant.org/version/1/4][version] 90 | 91 | [homepage]: http://contributor-covenant.org 92 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /moat370/sh/moat370_functions_datatypes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #************************************************************************ 3 | # 4 | # Copyright 2021 Rodrigo Jorge 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License" 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES -o CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | #************************************************************************ 19 | 20 | get_date_time () 21 | { 22 | date '+%Y%m%d_%H%M%S' 23 | } 24 | 25 | get_time () 26 | { 27 | date '+%H:%M:%S' 28 | } 29 | 30 | get_secs () 31 | { 32 | date '+%s' 33 | } 34 | 35 | convert_secs () 36 | { 37 | local h m s v_sec 38 | v_sec="$1" 39 | # Return seconds in HH:MI:SS format. 40 | h=$(do_calc 'v_sec/3600') 41 | m=$(do_calc '(v_sec%3600)/60') 42 | s=$(do_calc 'v_sec%60') 43 | printf "%02d:%02d:%02d\n" $h $m $s 44 | # The OR TRUE is due to output 0 gives a return 1. 45 | } 46 | 47 | trim_var () 48 | { 49 | 50 | set +u 51 | local in_char="$2" 52 | fc_enable_set_u 53 | [ -z "${in_char}" ] && in_char=" " 54 | 55 | sed "s/^${in_char}*//g ; s/${in_char}*$//g" <<< "$1" 56 | } 57 | 58 | upper_var () 59 | { 60 | tr [:lower:] [:upper:] <<< "$1" 61 | } 62 | 63 | lower_var () 64 | { 65 | tr [:upper:] [:lower:] <<< "$1" 66 | } 67 | 68 | greatest_num () 69 | { 70 | if [ $1 -gt $2 ] 71 | then 72 | echo $1 73 | else 74 | echo $2 75 | fi 76 | } 77 | 78 | check_input_format () 79 | { 80 | local INPUT_DATE="$1" 81 | local INPUT_FORMAT="%Y-%m-%d" 82 | local OUTPUT_FORMAT="%Y-%m-%d" 83 | local UNAME=$(uname) 84 | 85 | if [ "$UNAME" = "Darwin" ] # Mac OS X 86 | then 87 | date -j -f "$INPUT_FORMAT" "$INPUT_DATE" +"$OUTPUT_FORMAT" >/dev/null 2>&- || exit_error "Date ${INPUT_DATE} in wrong format. Specify YYYY-MM-DD." 88 | elif [ "$UNAME" = "Linux" ] # Linux 89 | then 90 | date -d "$INPUT_DATE" +"$OUTPUT_FORMAT" >/dev/null 2>&- || exit_error "Date ${INPUT_DATE} in wrong format. Specify YYYY-MM-DD." 91 | else # Unsupported system 92 | date -d "$INPUT_DATE" +"$OUTPUT_FORMAT" >/dev/null 2>&- || exit_error "Unsupported system" 93 | fi 94 | [ ${#INPUT_DATE} -eq 10 ] || exit_error "Date ${INPUT_DATE} in wrong format. Specify YYYY-MM-DD." 95 | } 96 | 97 | ConvYMDToEpoch () 98 | { 99 | local v_in_date="$1" 100 | case "$(uname -s)" in 101 | Linux*) echo $(date -u '+%s' -d ${v_in_date});; 102 | Darwin*) echo $(date -j -u -f '%Y-%m-%d %T' "${v_in_date} 00:00:00" +"%s");; 103 | *) echo 104 | esac 105 | } 106 | 107 | ConvEpochToYMD () 108 | { 109 | local v_in_epoch="$1" 110 | case "$(uname -s)" in 111 | Linux*) echo $(date -u '+%Y-%m-%d' -d @${v_in_epoch});; 112 | Darwin*) echo $(date -j -u -f '%s' "${v_in_epoch}" +"%Y-%m-%d");; 113 | *) echo 114 | esac 115 | } 116 | 117 | ConvSecsToDays () 118 | { 119 | local v_in_epoch=$1 120 | echo $(do_calc 'v_in_epoch/24/3600') 121 | } 122 | 123 | substr_var () 124 | { 125 | local v_len 126 | v_len=$(do_calc "$2+$3-1") 127 | cut -c$2-$v_len <<< "$1" 128 | } 129 | 130 | instr_var () 131 | { 132 | # 1 = String 133 | # 2 = Sub_String 134 | # 3 = Nth Occurrence. Default = 1 135 | # Output = Position. 0 = Not Found. 136 | 137 | local v_sstr v_occur 138 | 139 | set +u 140 | [ "$3" != "" ] && v_occur="$3" || v_occur=1 141 | fc_enable_set_u 142 | 143 | v_sstr=$(sed 's/[]\.|$(){}?+*^]/\\\\&/g' <<< "$2") 144 | $cmd_awk -v sstr="$v_sstr" -v occur="$v_occur" \ 145 | '{ 146 | i=1; idx=0; npos=1; str=$0 147 | while(i>0) { 148 | i=match(str,sstr); 149 | if(i>0) { 150 | idx += i; 151 | if (npos==occur) print idx; 152 | str=substr(str, i+1); 153 | npos += 1; 154 | } 155 | else if (idx==0) 156 | { 157 | print 0; 158 | } 159 | } 160 | }' <<< "$1" 161 | 162 | } 163 | 164 | ere_quote () 165 | { 166 | # Quote regex characters on string 167 | ${cmd_sed} 's/[]\.|$(){}?+*^]/\\&/g' <<< "$*" 168 | } 169 | 170 | do_calc () 171 | { 172 | echo "$(($1))" 173 | } 174 | 175 | #### END OF FILE #### -------------------------------------------------------------------------------- /moat370/js/decode.js: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Written by Rodrigo Jorge 3 | // ---------------------------------------------------------------------------- 4 | 5 | function get_password() { 6 | var orig_pass = prompt("Please enter password",""); 7 | if (orig_pass!=null && orig_pass!="") return orig_pass; 8 | } 9 | 10 | function get_param( name, url ) { 11 | if (!url) url = location.href; 12 | name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); 13 | var regexS = "[\\?&]"+name+"=([^&#]*)"; 14 | var regex = new RegExp( regexS ); 15 | var results = regex.exec( url ); 16 | return results == null ? null : results[1]; 17 | } 18 | 19 | function decompText (compressedtext) { 20 | try { 21 | // Decode base64 (convert ascii to binary) 22 | var strData = atob(compressedtext); 23 | // Convert binary string to character-number array 24 | var charData = strData.split('').map(function(x){return x.charCodeAt(0);}); 25 | // Turn number array into byte-array 26 | var binData = new Uint8Array(charData); 27 | // Gunzip 28 | var gunzip = new Zlib.Gunzip(binData); 29 | var data = gunzip.decompress(); 30 | // Convert gunzipped byteArray back to ascii string: 31 | // Broken for long strings 32 | // return String.fromCharCode.apply(null, new Uint16Array(data)); 33 | var strOut = new TextDecoder("utf-8").decode(data); 34 | return strOut; 35 | } 36 | catch(err) { 37 | return compressedtext; 38 | } 39 | } 40 | 41 | function rjorge_decrypt(secret, onload) { 42 | if (!secret) secret = get_password(); 43 | var dectext = ""; 44 | if (secret!=null && secret!="") dectext = CryptoJS.AES.decrypt(enctext, secret); 45 | if (dectext!=null && dectext!="") { 46 | try { 47 | var dectextutf = dectext.toString(CryptoJS.enc.Utf8); 48 | } 49 | catch(err) { 50 | if (!onload) alert ('Wrong Passphrase'); 51 | return; 52 | } 53 | if (enctext_comp) 54 | var dectextuncomp = decompText(dectextutf); 55 | else 56 | var dectextuncomp = dectextutf; 57 | if (!onload && isIndexPage()) { 58 | setParamCurURL ('decKey',secret); 59 | } 60 | else { 61 | loadHTML(dectextuncomp); 62 | // Add decKey to all page links 63 | appendPassURL('decKey',secret); 64 | } 65 | } 66 | } 67 | 68 | function rjorge_decomp() { 69 | var dectextuncomp = decompText(enctext); 70 | loadHTML(dectextuncomp); 71 | } 72 | 73 | function loadHTML(htmltext) { 74 | document.getElementById("rjorge_block").innerHTML = htmltext; 75 | // When HTML is decoded,