github.com/netdata/go.d.plugin@v0.58.1/modules/postgres/do_query_databases.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package postgres
     4  
     5  import (
     6  	"fmt"
     7  )
     8  
     9  func (p *Postgres) doQueryDatabasesMetrics() error {
    10  	if err := p.doQueryDatabaseStats(); err != nil {
    11  		return fmt.Errorf("querying database stats error: %v", err)
    12  	}
    13  	if err := p.doQueryDatabaseSize(); err != nil {
    14  		return fmt.Errorf("querying database size error: %v", err)
    15  	}
    16  	if p.isPGInRecovery() {
    17  		if err := p.doQueryDatabaseConflicts(); err != nil {
    18  			return fmt.Errorf("querying database conflicts error: %v", err)
    19  		}
    20  	}
    21  	if err := p.doQueryDatabaseLocks(); err != nil {
    22  		return fmt.Errorf("querying database locks error: %v", err)
    23  	}
    24  	return nil
    25  }
    26  
    27  func (p *Postgres) doQueryDatabaseStats() error {
    28  	q := queryDatabaseStats()
    29  
    30  	var db string
    31  	return p.doQuery(q, func(column, value string, _ bool) {
    32  		switch column {
    33  		case "datname":
    34  			db = value
    35  			p.getDBMetrics(db).updated = true
    36  		case "numbackends":
    37  			p.getDBMetrics(db).numBackends = parseInt(value)
    38  		case "datconnlimit":
    39  			p.getDBMetrics(db).datConnLimit = parseInt(value)
    40  		case "xact_commit":
    41  			p.getDBMetrics(db).xactCommit = parseInt(value)
    42  		case "xact_rollback":
    43  			p.getDBMetrics(db).xactRollback = parseInt(value)
    44  		case "blks_read_bytes":
    45  			p.getDBMetrics(db).blksRead.last = parseInt(value)
    46  		case "blks_hit_bytes":
    47  			p.getDBMetrics(db).blksHit.last = parseInt(value)
    48  		case "tup_returned":
    49  			p.getDBMetrics(db).tupReturned.last = parseInt(value)
    50  		case "tup_fetched":
    51  			p.getDBMetrics(db).tupFetched.last = parseInt(value)
    52  		case "tup_inserted":
    53  			p.getDBMetrics(db).tupInserted = parseInt(value)
    54  		case "tup_updated":
    55  			p.getDBMetrics(db).tupUpdated = parseInt(value)
    56  		case "tup_deleted":
    57  			p.getDBMetrics(db).tupDeleted = parseInt(value)
    58  		case "conflicts":
    59  			p.getDBMetrics(db).conflicts = parseInt(value)
    60  		case "temp_files":
    61  			p.getDBMetrics(db).tempFiles = parseInt(value)
    62  		case "temp_bytes":
    63  			p.getDBMetrics(db).tempBytes = parseInt(value)
    64  		case "deadlocks":
    65  			p.getDBMetrics(db).deadlocks = parseInt(value)
    66  		}
    67  	})
    68  }
    69  
    70  func (p *Postgres) doQueryDatabaseSize() error {
    71  	q := queryDatabaseSize(p.pgVersion)
    72  
    73  	var db string
    74  	return p.doQuery(q, func(column, value string, _ bool) {
    75  		switch column {
    76  		case "datname":
    77  			db = value
    78  		case "size":
    79  			p.getDBMetrics(db).size = newInt(parseInt(value))
    80  		}
    81  	})
    82  }
    83  
    84  func (p *Postgres) doQueryDatabaseConflicts() error {
    85  	q := queryDatabaseConflicts()
    86  
    87  	var db string
    88  	return p.doQuery(q, func(column, value string, _ bool) {
    89  		switch column {
    90  		case "datname":
    91  			db = value
    92  			p.getDBMetrics(db).updated = true
    93  		case "confl_tablespace":
    94  			p.getDBMetrics(db).conflTablespace = parseInt(value)
    95  		case "confl_lock":
    96  			p.getDBMetrics(db).conflLock = parseInt(value)
    97  		case "confl_snapshot":
    98  			p.getDBMetrics(db).conflSnapshot = parseInt(value)
    99  		case "confl_bufferpin":
   100  			p.getDBMetrics(db).conflBufferpin = parseInt(value)
   101  		case "confl_deadlock":
   102  			p.getDBMetrics(db).conflDeadlock = parseInt(value)
   103  		}
   104  	})
   105  }
   106  
   107  func (p *Postgres) doQueryDatabaseLocks() error {
   108  	q := queryDatabaseLocks()
   109  
   110  	var db, mode string
   111  	var granted bool
   112  	return p.doQuery(q, func(column, value string, _ bool) {
   113  		switch column {
   114  		case "datname":
   115  			db = value
   116  			p.getDBMetrics(db).updated = true
   117  		case "mode":
   118  			mode = value
   119  		case "granted":
   120  			granted = value == "true" || value == "t"
   121  		case "locks_count":
   122  			// https://github.com/postgres/postgres/blob/7c34555f8c39eeefcc45b3c3f027d7a063d738fc/src/include/storage/lockdefs.h#L36-L45
   123  			// https://www.postgresql.org/docs/7.2/locking-tables.html
   124  			switch {
   125  			case mode == "AccessShareLock" && granted:
   126  				p.getDBMetrics(db).accessShareLockHeld = parseInt(value)
   127  			case mode == "AccessShareLock":
   128  				p.getDBMetrics(db).accessShareLockAwaited = parseInt(value)
   129  			case mode == "RowShareLock" && granted:
   130  				p.getDBMetrics(db).rowShareLockHeld = parseInt(value)
   131  			case mode == "RowShareLock":
   132  				p.getDBMetrics(db).rowShareLockAwaited = parseInt(value)
   133  			case mode == "RowExclusiveLock" && granted:
   134  				p.getDBMetrics(db).rowExclusiveLockHeld = parseInt(value)
   135  			case mode == "RowExclusiveLock":
   136  				p.getDBMetrics(db).rowExclusiveLockAwaited = parseInt(value)
   137  			case mode == "ShareUpdateExclusiveLock" && granted:
   138  				p.getDBMetrics(db).shareUpdateExclusiveLockHeld = parseInt(value)
   139  			case mode == "ShareUpdateExclusiveLock":
   140  				p.getDBMetrics(db).shareUpdateExclusiveLockAwaited = parseInt(value)
   141  			case mode == "ShareLock" && granted:
   142  				p.getDBMetrics(db).shareLockHeld = parseInt(value)
   143  			case mode == "ShareLock":
   144  				p.getDBMetrics(db).shareLockAwaited = parseInt(value)
   145  			case mode == "ShareRowExclusiveLock" && granted:
   146  				p.getDBMetrics(db).shareRowExclusiveLockHeld = parseInt(value)
   147  			case mode == "ShareRowExclusiveLock":
   148  				p.getDBMetrics(db).shareRowExclusiveLockAwaited = parseInt(value)
   149  			case mode == "ExclusiveLock" && granted:
   150  				p.getDBMetrics(db).exclusiveLockHeld = parseInt(value)
   151  			case mode == "ExclusiveLock":
   152  				p.getDBMetrics(db).exclusiveLockAwaited = parseInt(value)
   153  			case mode == "AccessExclusiveLock" && granted:
   154  				p.getDBMetrics(db).accessExclusiveLockHeld = parseInt(value)
   155  			case mode == "AccessExclusiveLock":
   156  				p.getDBMetrics(db).accessExclusiveLockAwaited = parseInt(value)
   157  			}
   158  		}
   159  	})
   160  }