[
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: \"pip\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"weekly\"\n  - package-ecosystem: \"github-actions\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "content": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# You may wish to alter this file to override the set of languages analyzed,\n# or to provide custom queries or build logic.\n#\n# ******** NOTE ********\n# We have attempted to detect the languages in your repository. Please check\n# the `language` matrix defined below to confirm you have the correct set of\n# supported CodeQL languages.\n#\nname: \"CodeQL\"\n\non:\n  push:\n    branches: [ \"main\" ]\n  pull_request:\n    # The branches below must be a subset of the branches above\n    branches: [ \"main\" ]\n  schedule:\n    - cron: '35 7 * * 6'\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ 'python' ]\n        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]\n        # Use only 'java' to analyze code written in Java, Kotlin or both\n        # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both\n        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v6\n\n    # Initializes the CodeQL tools for scanning.\n    - name: Initialize CodeQL\n      uses: github/codeql-action/init@v4\n      with:\n        languages: ${{ matrix.language }}\n        # If you wish to specify custom queries, you can do so here or in a config file.\n        # By default, queries listed here will override any specified in a config file.\n        # Prefix the list here with \"+\" to use these queries and those in the config file.\n\n        # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs\n        # queries: security-extended,security-and-quality\n\n\n    # Autobuild attempts to build any compiled languages  (C/C++, C#, Go, or Java).\n    # If this step fails, then you should remove it and run the build manually (see below)\n    - name: Autobuild\n      uses: github/codeql-action/autobuild@v4\n\n    # ℹ️ Command-line programs to run using the OS shell.\n    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun\n\n    #   If the Autobuild fails above, remove it and uncomment the following three lines.\n    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.\n\n    # - run: |\n    #   echo \"Run, Build Application using script\"\n    #   ./location_of_script_within_repo/buildscript.sh\n\n    - name: Perform CodeQL Analysis\n      uses: github/codeql-action/analyze@v4\n      with:\n        category: \"/language:${{matrix.language}}\"\n"
  },
  {
    "path": ".github/workflows/integration_tests.yml",
    "content": "name: Basic Integration Tests\n\non:\n  pull_request:\n  push:\n    branches:\n      - main\n\njobs:\n  config:\n    strategy:\n      fail-fast: false\n      matrix:\n        psql_version: ['14.20', '15.15', '16.11', '17.7', '18.1']\n        python_version: ['3.10', '3.11', '3.12']\n\n    name: PostgreSQL ${{ matrix.psql_version }} and Python ${{ matrix.python_version }} integration test\n    runs-on: ubuntu-24.04\n\n    steps:\n      - name: Checkout source code\n        uses: actions/checkout@v6\n\n      - uses: actions/setup-python@v6\n        with:\n          python-version: ${{ matrix.python_version }}\n\n      - name: Show Python version\n        run: python --version\n\n      - name: Install needed tools\n        run: |\n          sudo apt install python3-bpfcc systemtap-sdt-dev flex bison lcov build-essential libxml2-dev libssl-dev zlib1g-dev libreadline-dev\n\n      - name: Cache PostgreSQL build ${{ matrix.psql_version }}\n        id: postgresql-cache\n        uses: actions/cache@v5\n        with:\n          path: ~/postgresql\n          key: postgresql-${{ matrix.psql_version }}-${{ hashFiles('.github/workflows/*') }}\n\n      - name: Build PostgreSQL\n        if: steps.postgresql-cache.outputs.cache-hit != 'true'\n        run: |\n          mkdir -p ~/postgresql\n          mkdir -p ~/postgresql/src/${{ matrix.psql_version }}\n          mkdir -p ~/postgresql/bin/${{ matrix.psql_version }}\n\n          # Data dir is not part of the cache\n          mkdir -p ~/postgresql_data/${{ matrix.psql_version }}\n\n          cd ~/postgresql/src/${{ matrix.psql_version }}\n          wget -q -O postgresql.tar.bz2 https://ftp.postgresql.org/pub/source/v${{ matrix.psql_version }}/postgresql-${{ matrix.psql_version }}.tar.bz2\n          \n          tar jxf postgresql.tar.bz2 --strip-components 1 -C .\n\n          CFLAGS=\"-ggdb -Og -g3 -fno-omit-frame-pointer\" ./configure --prefix=$HOME/postgresql/bin/${{ matrix.psql_version }} --with-openssl --with-readline --with-zlib --with-libxml --enable-dtrace\n          make -j 8\n\n      - name: Install PostgreSQL\n        run: | \n          cd ~/postgresql/src/${{ matrix.psql_version }}\n\n          make install\n\n          ~/postgresql/bin/${{ matrix.psql_version }}/bin/initdb -D ~/postgresql_data/${{ matrix.psql_version }}\n          ~/postgresql/bin/${{ matrix.psql_version }}/bin/pg_ctl -D ~/postgresql_data/${{ matrix.psql_version }} start\n\n          #sudo apt install curl ca-certificates gnupg\n          #sudo curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null\n          #sudo sh -c 'echo \"deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main\" > /etc/apt/sources.list.d/pgdg.list'\n          #sudo apt update\n          #sudo apt install postgresql-${{ matrix.psql_version }} postgresql-${{ matrix.psql_version }}-dbgsym\n          #sudo /etc/init.d/postgresql start ${{ matrix.psql_version }}\n          #dpkg -L postgresql-${{ matrix.psql_version }}-dbgsym\n          #readelf --string-dump=.gnu_debuglink /usr/lib/postgresql/${{ matrix.psql_version }}/bin/postgres\n          #objdump -TC /usr/lib/postgresql/${{ matrix.psql_version }}/bin/postgres\n\n      - name: Install package\n        run: sudo python -m pip install .\n      \n      - name: Check that pg_lock_tracer can be executed\n        run: |\n           pg_lock_tracer --version\n           sudo pg_lock_tracer -x ~/postgresql/bin/${{ matrix.psql_version }}/bin/postgres -v -p $(pidof postgres) --statistics --dry-run\n\n      - name: Check that pg_lw_lock_tracer can be executed\n        run: |\n           pg_lw_lock_tracer --version\n           sudo pg_lw_lock_tracer -p $(pidof postgres) --dry-run\n\n      - name: Check that pg_row_lock_tracer can be executed\n        run: |\n          pg_row_lock_tracer --version\n          sudo pg_row_lock_tracer -x ~/postgresql/bin/${{ matrix.psql_version }}/bin/postgres -v -p $(pidof postgres) --statistics --dry-run\n\n      - name: Check that animate_lock_graph can be executed\n        run: |\n           animate_lock_graph --version\n           animate_lock_graph -o animation.html -i examples/create_table_trace.json\n           diff animation.html -i examples/create_table_trace.html\n\n      - name: Check that pg_spinlock_delay_tracer can be executed\n        run: |\n           pg_spinlock_delay_tracer --version\n           sudo pg_spinlock_delay_tracer -x ~/postgresql/bin/${{ matrix.psql_version }}/bin/postgres -v -p $(pidof postgres) --dry-run\n"
  },
  {
    "path": ".github/workflows/pr_handling.yml",
    "content": "name: PR Handling\n\n#################\n# NOTE: We are using pull_request_target here:\n#       https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.\n#       \n#       So, only API calls should be made in the actions defined here. The\n#       committed code should _NOT_ be touched in any case.\n#################\n\non:\n  pull_request_target:\n    types: [ opened, reopened ]\n    \njobs:\n  assign-pr:\n    name: Assign PR to author\n    runs-on: ubuntu-latest\n    steps:\n      - uses: toshimaru/auto-author-assign@v3.0.2\n \n"
  },
  {
    "path": ".github/workflows/python_publish.yml",
    "content": "# Based on https://github.com/actions/starter-workflows/blob/main/ci/python-publish.yml\nname: Upload Python Package\n\non:\n  release:\n    types: [published]\n\npermissions:\n  contents: read\n\njobs:\n  deploy:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v6\n\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install build\n        pip install twine\n        pip install dunamai\n        # See https://github.com/pypa/twine/issues/1216\n        pip install -U packaging\n    \n    - name: Show version based on git tag\n      run: dunamai from git --style semver\n\n    - name: Ensure that program and tag version match\n      if: github.event_name == 'release'\n      run: |\n        PACKAGE_VERSION=$(python -c \"from src.pg_lock_tracer import __version__; print(__version__)\")\n        GIT_VERSION=$(dunamai from git --style semver)\n        if [[ \"$PACKAGE_VERSION\" != \"$GIT_VERSION\" ]]; then\n           echo \"Version mismatch ${PACKAGE_VERSION} / ${GIT_VERSION}\"\n           exit 1\n        fi\n\n    - name: Build package\n      run: python -m build\n\n    - name: Upload to test.pypi\n      if: github.event_name == 'release'\n      run: 'twine upload --non-interactive --repository testpypi dist/*'\n      env:\n        TWINE_USERNAME: '__token__'\n        TWINE_PASSWORD: '${{ secrets.TWINE_PASSWORD_TEST }}'\n\n    - name: Upload to pypi\n      if: github.event_name == 'release'\n      run: 'twine upload --non-interactive dist/*'\n      env:\n        TWINE_USERNAME: '__token__'\n        TWINE_PASSWORD: '${{ secrets.TWINE_PASSWORD }}'\n"
  },
  {
    "path": ".github/workflows/stale.yml",
    "content": "name: 'Close stale issues'\n\"on\":\n  schedule:\n    - cron: '30 1 * * *'\n  workflow_dispatch:\n\njobs:\n  stale:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/stale@v10\n        with:\n          # Don't process PRs\n          days-before-stale: -1\n\n          # Process only issues\n          days-before-issue-stale: 60\n          days-before-issue-close: 30\n\n          # Add this label after 'days-before-issue-stale' days to mark it as stale\n          stale-issue-label: 'no-activity'\n\n          # Process only issues that contain the label 'waiting-for-author'\n          only-labels: 'need-more-info'\n\n          close-issue-message: 'This issue was closed because it has been stalled for several weeks with no activity.'\n"
  },
  {
    "path": ".github/workflows/tests.yml",
    "content": "name: Basic Project Tests\non:\n  pull_request:\n  push:\n    branches:\n      - main\n\njobs:\n  tests:\n    name: Perform unit tests\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v6\n\n      - name: Install needed tools\n        run: |\n          sudo apt update\n          sudo apt install python3-bpfcc\n\n      - name: Setup python 3.10\n        uses: actions/setup-python@v6\n        with:\n          python-version: '3.10'\n\n      - name: Copy distribution BPF packages\n        run: cp -av /usr/lib/python3/dist-packages/bcc* $(python -c \"import sysconfig; print(sysconfig.get_path('platlib'))\")\n\n      - name: Install package\n        run: python -m pip install .\n\n      - name: Install development requirements\n        run: python -m pip install -r requirements_dev.txt\n\n      - name: Execute unit tests\n        run: pytest\n\n  linter:\n    name: Run Linter and check formatting\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v6\n\n      - name: Install needed tools\n        run: |\n          sudo apt update\n          sudo apt install clang-format python3-bpfcc\n\n      - name: Install development requirements\n        run: python -m pip install -r requirements_dev.txt\n\n      - name: Run pylint\n        run: pylint src tests\n  \n      - name: Check code format with black\n        run: black --check --diff src tests\n      \n      - name: Run clang-format\n        run: clang-format --dry-run --Werror src/pg_lock_tracer/bpf/*.c\n"
  },
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\npip-wheel-metadata/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n.python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# VScode\n.vscode/"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [2022] [Jan Nidzwetzki]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# Lock tracing tools for PostgreSQL\n[![Build Status](https://github.com/jnidzwetzki/pg-lock-tracer/actions/workflows/tests.yml/badge.svg)](https://github.com/jnidzwetzki/pg-lock-tracer/actions/workflows/tests.yml)\n[![PyPI](https://img.shields.io/pypi/v/pg-lock-tracer?color=green)](https://pypi.org/project/pg-lock-tracer/)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/pg-lock-tracer)](https://pypi.org/project/pg-lock-tracer/)\n[![Release date](https://img.shields.io/github/release-date/jnidzwetzki/pg-lock-tracer)](https://github.com/jnidzwetzki/pg-lock-tracer/)\n[![GitHub Repo stars](https://img.shields.io/github/stars/jnidzwetzki/pg-lock-tracer?style=social)](https://github.com/jnidzwetzki/pg-lock-tracer/)\n\nA set of eBPF-based tools designed to observe and visualize PostgreSQL 🐘 locking activity. These tools help users understand lock timing and contention behavior.\n\nKey components:\n\n- `pg_lock_tracer`: heavy lock tracer (e.g., table level locks)\n- `pg_lw_lock_tracer`: lightweight lock (LWLock) tracer\n- `pg_row_lock_tracer`: row-level lock tracer\n- `pg_spinlock_delay_tracer`: spinlock delay tracer\n- `animate_lock_graph`: render animated lock graphs from `pg_lock_tracer` tracer output\n\n__Note:__ These tools rely on [eBPF](https://ebpf.io/) (_Extended Berkeley Packet Filter_) technology. At the moment, PostgreSQL 14, 15, 16, 17, and 18 are supported (see additional information below).\n\n\n## ⚡ Quickstart\n1. Install the pg-lock-tracer tools:\n\n```\n$ pip install pg-lock-tracer\n```\n\n2. Identify the PostgreSQL server binary used by your instance (e.g., `/usr/lib/postgresql/X/bin/postgres`).\n3. Start tracing a running Postgres PID (requires root privileges):\n\n```\n$ sudo pg_lock_tracer -x /path/to/postgres\n```\n\nThis shows the locking activity of all processes running this PostgreSQL binary. \n\n# pg_lock_tracer\n`pg_lock_tracer` observes the locking activity of a running PostgreSQL process (using _eBPF_ and _UProbes_). In contrast to the information that is present in the table `pg_locks` (which provides information about which locks are _currently_ requested), `pg_lock_tracer` gives you a continuous view of the locking activity and collects statistics and timings.\n\nThe tracer also allows dumping the output as JSON-formatted lines, which allows further processing with additional tools. This repository also contains the script `animate_lock_graph`, which provides an animated version of the taken looks.\n\n## 🧪 Usage Examples\n```\n# Trace use binary '/home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres' for tracing\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres\n\n# Trace use binary '/home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres' for tracing and trace pid 1234\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234\n\n# Trace two PIDs\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -p 5678\n\n# Be verbose\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -v \n\n# Use the given db connection to access the catalog of PID 1234 to resolve OIDs\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -r 1234:psql://jan@localhost/test2\n\n# Output in JSON format\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -j\n\n# Print stacktrace on deadlock\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -s DEADLOCK\n\n# Print stacktrace for locks and deadlocks\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -s LOCK DEADLOCK\n\n# Trace only Transaction and Query related events\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -t TRANSACTION QUERY\n\n# Write the output into file 'trace'\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -o trace\n\n# Show statistics about locks\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 --statistics\n\n# Create an animated lock graph (with Oids)\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -j -o locks.json\nanimate_lock_graph -i lock -o locks.html\n\n# Create an animated lock graph (with table names)\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -j -r 1234:psql://jan@localhost/test2 -o locks.json\nanimate_lock_graph -i lock -o locks.html\n```\n\n## 📄 Example Output\n\nCLI: `pg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_2_DEBUG/bin/postgres -p 327578 -r 327578:sql://jan@localhost/test2 --statistics`\n\nSQL Query: `create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);`\n\nTracer Output:\n\n```\n745064333930117 [Pid 327578] Query begin 'create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);'\n745064333965769 [Pid 327578] Transaction begin\n745064334157640 [Pid 327578] Table open 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334176147 [Pid 327578] Lock object 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334204453 [Pid 327578] Lock granted (fastpath) 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334224361 [Pid 327578] Lock granted (local) 3079 (pg_catalog.pg_extension) AccessShareLock (Already hold local 0)\n745064334243659 [Pid 327578] Lock was acquired in 67512 ns\n[...]\n```\n\n<details>\n  <summary>Full Output</summary>\n\n```\n===> Ready to trace queries\n745064333930117 [Pid 327578] Query begin 'create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);'\n745064333965769 [Pid 327578] Transaction begin\n745064334157640 [Pid 327578] Table open 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334176147 [Pid 327578] Lock object 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334204453 [Pid 327578] Lock granted (fastpath) 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334224361 [Pid 327578] Lock granted (local) 3079 (pg_catalog.pg_extension) AccessShareLock (Already hold local 0)\n745064334243659 [Pid 327578] Lock was acquired in 67512 ns\n745064334285877 [Pid 327578] Lock object 3081 (pg_catalog.pg_extension_name_index) AccessShareLock\n745064334309610 [Pid 327578] Lock granted (fastpath) 3081 (pg_catalog.pg_extension_name_index) AccessShareLock\n745064334328475 [Pid 327578] Lock granted (local) 3081 (pg_catalog.pg_extension_name_index) AccessShareLock (Already hold local 0)\n745064334345266 [Pid 327578] Lock was acquired in 59389 ns\n745064334562977 [Pid 327578] Lock ungranted (fastpath) 3081 (pg_catalog.pg_extension_name_index) AccessShareLock\n745064334583578 [Pid 327578] Lock ungranted (local) 3081 (pg_catalog.pg_extension_name_index) AccessShareLock (Hold local 0)\n745064334608957 [Pid 327578] Table close 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334631046 [Pid 327578] Lock ungranted (fastpath) 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334649932 [Pid 327578] Lock ungranted (local) 3079 (pg_catalog.pg_extension) AccessShareLock (Hold local 0)\n745064334671897 [Pid 327578] Table open 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334688382 [Pid 327578] Lock object 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334712042 [Pid 327578] Lock granted (fastpath) 3079 (pg_catalog.pg_extension) AccessShareLock\n745064334731081 [Pid 327578] Lock granted (local) 3079 (pg_catalog.pg_extension) AccessShareLock (Already hold local 0)\n745064334748288 [Pid 327578] Lock was acquired in 59906 ns\n745064334772367 [Pid 327578] Lock object 3081 (pg_catalog.pg_extension_name_index) AccessShareLock\n745064334795943 [Pid 327578] Lock granted (fastpath) 3081 (pg_catalog.pg_extension_name_index) AccessShareLock\n745064334814983 [Pid 327578] Lock granted (local) 3081 (pg_catalog.pg_extension_name_index) AccessShareLock (Already hold local 0)\n745064334832570 [Pid 327578] Lock was acquired in 60203 ns\n745064334953192 [Pid 327578] Lock ungranted (fastpath) 3081 (pg_catalog.pg_extension_name_index) AccessShareLock\n745064334973518 [Pid 327578] Lock ungranted (local) 3081 (pg_catalog.pg_extension_name_index) AccessShareLock (Hold local 0)\n745064334997936 [Pid 327578] Table close 3079 (pg_catalog.pg_extension) AccessShareLock\n745064335019473 [Pid 327578] Lock ungranted (fastpath) 3079 (pg_catalog.pg_extension) AccessShareLock\n745064335037880 [Pid 327578] Lock ungranted (local) 3079 (pg_catalog.pg_extension) AccessShareLock (Hold local 0)\n745064335901618 [Pid 327578] Table open 1259 (pg_catalog.pg_class) AccessShareLock\n745064335918354 [Pid 327578] Lock object 1259 (pg_catalog.pg_class) AccessShareLock\n745064335941911 [Pid 327578] Lock granted (fastpath) 1259 (pg_catalog.pg_class) AccessShareLock\n745064335960211 [Pid 327578] Lock granted (local) 1259 (pg_catalog.pg_class) AccessShareLock (Already hold local 0)\n745064335976642 [Pid 327578] Lock was acquired in 58288 ns\n745064335999654 [Pid 327578] Lock object 2663 (pg_catalog.pg_class_relname_nsp_index) AccessShareLock\n745064336022776 [Pid 327578] Lock granted (fastpath) 2663 (pg_catalog.pg_class_relname_nsp_index) AccessShareLock\n745064336040926 [Pid 327578] Lock granted (local) 2663 (pg_catalog.pg_class_relname_nsp_index) AccessShareLock (Already hold local 0)\n745064336057158 [Pid 327578] Lock was acquired in 57504 ns\n745064336187786 [Pid 327578] Lock ungranted (fastpath) 2663 (pg_catalog.pg_class_relname_nsp_index) AccessShareLock\n745064336207011 [Pid 327578] Lock ungranted (local) 2663 (pg_catalog.pg_class_relname_nsp_index) AccessShareLock (Hold local 0)\n745064336230761 [Pid 327578] Table close 1259 (pg_catalog.pg_class) AccessShareLock\n745064336252413 [Pid 327578] Lock ungranted (fastpath) 1259 (pg_catalog.pg_class) AccessShareLock\n745064336270811 [Pid 327578] Lock ungranted (local) 1259 (pg_catalog.pg_class) AccessShareLock (Hold local 0)\n745064336314237 [Pid 327578] Lock granted 2615 (pg_catalog.pg_namespace) AccessShareLock (Requested locks 1)\n745064336331450 [Pid 327578] Lock granted (local) 2615 (pg_catalog.pg_namespace) AccessShareLock (Already hold local 0)\n745064336402316 [Pid 327578] Lock granted (local) 2615 (pg_catalog.pg_namespace) AccessShareLock (Already hold local 1)\n745064336543618 [Pid 327578] Table open 1259 (pg_catalog.pg_class) RowExclusiveLock\n745064336560502 [Pid 327578] Lock object 1259 (pg_catalog.pg_class) RowExclusiveLock\n745064336584633 [Pid 327578] Lock granted (fastpath) 1259 (pg_catalog.pg_class) RowExclusiveLock\n745064336602915 [Pid 327578] Lock granted (local) 1259 (pg_catalog.pg_class) RowExclusiveLock (Already hold local 0)\n745064336619969 [Pid 327578] Lock was acquired in 59467 ns\n745064336655328 [Pid 327578] Table open 1247 (pg_catalog.pg_type) AccessShareLock\n745064336671769 [Pid 327578] Lock object 1247 (pg_catalog.pg_type) AccessShareLock\n745064336696072 [Pid 327578] Lock granted (fastpath) 1247 (pg_catalog.pg_type) AccessShareLock\n745064336714540 [Pid 327578] Lock granted (local) 1247 (pg_catalog.pg_type) AccessShareLock (Already hold local 0)\n745064336731130 [Pid 327578] Lock was acquired in 59361 ns\n745064336755221 [Pid 327578] Lock object 2704 (pg_catalog.pg_type_typname_nsp_index) AccessShareLock\n745064336778586 [Pid 327578] Lock granted (fastpath) 2704 (pg_catalog.pg_type_typname_nsp_index) AccessShareLock\n745064336797018 [Pid 327578] Lock granted (local) 2704 (pg_catalog.pg_type_typname_nsp_index) AccessShareLock (Already hold local 0)\n745064336813397 [Pid 327578] Lock was acquired in 58176 ns\n745064336932804 [Pid 327578] Lock ungranted (fastpath) 2704 (pg_catalog.pg_type_typname_nsp_index) AccessShareLock\n745064336952174 [Pid 327578] Lock ungranted (local) 2704 (pg_catalog.pg_type_typname_nsp_index) AccessShareLock (Hold local 0)\n745064336975237 [Pid 327578] Table close 1247 (pg_catalog.pg_type) AccessShareLock\n745064336996581 [Pid 327578] Lock ungranted (fastpath) 1247 (pg_catalog.pg_type) AccessShareLock\n745064337014858 [Pid 327578] Lock ungranted (local) 1247 (pg_catalog.pg_type) AccessShareLock (Hold local 0)\n745064337047504 [Pid 327578] Lock object 2662 (pg_catalog.pg_class_oid_index) AccessShareLock\n745064337070928 [Pid 327578] Lock granted (fastpath) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock\n745064337089515 [Pid 327578] Lock granted (local) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock (Already hold local 0)\n745064337106032 [Pid 327578] Lock was acquired in 58528 ns\n745064337183488 [Pid 327578] Lock ungranted (fastpath) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock\n745064337202563 [Pid 327578] Lock ungranted (local) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock (Hold local 0)\n745064337621853 [Pid 327578] Table open 1247 (pg_catalog.pg_type) AccessShareLock\n745064337638996 [Pid 327578] Lock object 1247 (pg_catalog.pg_type) AccessShareLock\n745064337661950 [Pid 327578] Lock granted (fastpath) 1247 (pg_catalog.pg_type) AccessShareLock\n745064337681169 [Pid 327578] Lock granted (local) 1247 (pg_catalog.pg_type) AccessShareLock (Already hold local 0)\n745064337697945 [Pid 327578] Lock was acquired in 58949 ns\n745064337723254 [Pid 327578] Lock object 2703 (pg_catalog.pg_type_oid_index) AccessShareLock\n745064337746949 [Pid 327578] Lock granted (fastpath) 2703 (pg_catalog.pg_type_oid_index) AccessShareLock\n745064337765491 [Pid 327578] Lock granted (local) 2703 (pg_catalog.pg_type_oid_index) AccessShareLock (Already hold local 0)\n745064337781897 [Pid 327578] Lock was acquired in 58643 ns\n745064337865717 [Pid 327578] Lock ungranted (fastpath) 2703 (pg_catalog.pg_type_oid_index) AccessShareLock\n745064337885245 [Pid 327578] Lock ungranted (local) 2703 (pg_catalog.pg_type_oid_index) AccessShareLock (Hold local 0)\n745064337907299 [Pid 327578] Table close 1247 (pg_catalog.pg_type) AccessShareLock\n745064337928390 [Pid 327578] Lock ungranted (fastpath) 1247 (pg_catalog.pg_type) AccessShareLock\n745064337946792 [Pid 327578] Lock ungranted (local) 1247 (pg_catalog.pg_type) AccessShareLock (Hold local 0)\n745064337970694 [Pid 327578] Table open 1247 (pg_catalog.pg_type) RowExclusiveLock\n745064337987065 [Pid 327578] Lock object 1247 (pg_catalog.pg_type) RowExclusiveLock\n745064338010254 [Pid 327578] Lock granted (fastpath) 1247 (pg_catalog.pg_type) RowExclusiveLock\n745064338028898 [Pid 327578] Lock granted (local) 1247 (pg_catalog.pg_type) RowExclusiveLock (Already hold local 0)\n745064338045413 [Pid 327578] Lock was acquired in 58348 ns\n745064338073508 [Pid 327578] Lock object 2703 (pg_catalog.pg_type_oid_index) AccessShareLock\n745064338096688 [Pid 327578] Lock granted (fastpath) 2703 (pg_catalog.pg_type_oid_index) AccessShareLock\n745064338114955 [Pid 327578] Lock granted (local) 2703 (pg_catalog.pg_type_oid_index) AccessShareLock (Already hold local 0)\n745064338131934 [Pid 327578] Lock was acquired in 58426 ns\n745064338198858 [Pid 327578] Lock ungranted (fastpath) 2703 (pg_catalog.pg_type_oid_index) AccessShareLock\n745064338218267 [Pid 327578] Lock ungranted (local) 2703 (pg_catalog.pg_type_oid_index) AccessShareLock (Hold local 0)\n745064338257754 [Pid 327578] Lock object 2703 (pg_catalog.pg_type_oid_index) RowExclusiveLock\n745064338281754 [Pid 327578] Lock granted (fastpath) 2703 (pg_catalog.pg_type_oid_index) RowExclusiveLock\n745064338300356 [Pid 327578] Lock granted (local) 2703 (pg_catalog.pg_type_oid_index) RowExclusiveLock (Already hold local 0)\n745064338317100 [Pid 327578] Lock was acquired in 59346 ns\n745064338343423 [Pid 327578] Lock object 2704 (pg_catalog.pg_type_typname_nsp_index) RowExclusiveLock\n745064338366354 [Pid 327578] Lock granted (fastpath) 2704 (pg_catalog.pg_type_typname_nsp_index) RowExclusiveLock\n745064338384776 [Pid 327578] Lock granted (local) 2704 (pg_catalog.pg_type_typname_nsp_index) RowExclusiveLock (Already hold local 0)\n745064338401188 [Pid 327578] Lock was acquired in 57765 ns\n745064338925851 [Pid 327578] Lock ungranted (fastpath) 2703 (pg_catalog.pg_type_oid_index) RowExclusiveLock\n745064338945562 [Pid 327578] Lock ungranted (local) 2703 (pg_catalog.pg_type_oid_index) RowExclusiveLock (Hold local 0)\n745064338969060 [Pid 327578] Lock ungranted (fastpath) 2704 (pg_catalog.pg_type_typname_nsp_index) RowExclusiveLock\n745064338987686 [Pid 327578] Lock ungranted (local) 2704 (pg_catalog.pg_type_typname_nsp_index) RowExclusiveLock (Hold local 0)\n745064339016433 [Pid 327578] Table open 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064339032833 [Pid 327578] Lock object 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064339056324 [Pid 327578] Lock granted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064339075245 [Pid 327578] Lock granted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Already hold local 0)\n745064339092056 [Pid 327578] Lock was acquired in 59223 ns\n745064339118530 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339141606 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339159893 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064339176278 [Pid 327578] Lock was acquired in 57748 ns\n745064339275302 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339295035 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064339320204 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339343605 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339362550 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064339379189 [Pid 327578] Lock was acquired in 58985 ns\n745064339466953 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339486483 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064339512103 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339535492 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339554170 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064339570785 [Pid 327578] Lock was acquired in 58682 ns\n745064339661539 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339680770 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064339706403 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339731859 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339750907 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064339767580 [Pid 327578] Lock was acquired in 61177 ns\n745064339855776 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064339875244 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064339898815 [Pid 327578] Table close 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064339920526 [Pid 327578] Lock ungranted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064339939861 [Pid 327578] Lock ungranted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Hold local 0)\n745064339961989 [Pid 327578] Table open 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064339978907 [Pid 327578] Lock object 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064340001670 [Pid 327578] Lock granted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064340020405 [Pid 327578] Lock granted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Already hold local 0)\n745064340036728 [Pid 327578] Lock was acquired in 57821 ns\n745064340060373 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064340083157 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064340101890 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064340118486 [Pid 327578] Lock was acquired in 58113 ns\n745064340198186 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064340219330 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064340250646 [Pid 327578] Lock object 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock\n745064340274684 [Pid 327578] Lock granted (fastpath) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock\n745064340293524 [Pid 327578] Lock granted (local) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock (Already hold local 0)\n745064340310202 [Pid 327578] Lock was acquired in 59556 ns\n745064340337112 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock\n745064340360031 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock\n745064340378739 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock (Already hold local 0)\n745064340395496 [Pid 327578] Lock was acquired in 58384 ns\n745064340576666 [Pid 327578] Lock ungranted (fastpath) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock\n745064340596299 [Pid 327578] Lock ungranted (local) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock (Hold local 0)\n745064340620661 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock\n745064340639350 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock (Hold local 0)\n745064340660990 [Pid 327578] Table close 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064340682154 [Pid 327578] Lock ungranted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064340700466 [Pid 327578] Lock ungranted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Hold local 0)\n745064340724983 [Pid 327578] Table close 1247 (pg_catalog.pg_type) RowExclusiveLock\n745064340745747 [Pid 327578] Lock ungranted (fastpath) 1247 (pg_catalog.pg_type) RowExclusiveLock\n745064340763978 [Pid 327578] Lock ungranted (local) 1247 (pg_catalog.pg_type) RowExclusiveLock (Hold local 0)\n745064340789474 [Pid 327578] Table open 1247 (pg_catalog.pg_type) AccessShareLock\n745064340805855 [Pid 327578] Lock object 1247 (pg_catalog.pg_type) AccessShareLock\n745064340828989 [Pid 327578] Lock granted (fastpath) 1247 (pg_catalog.pg_type) AccessShareLock\n745064340847526 [Pid 327578] Lock granted (local) 1247 (pg_catalog.pg_type) AccessShareLock (Already hold local 0)\n745064340864256 [Pid 327578] Lock was acquired in 58401 ns\n745064340885838 [Pid 327578] Lock object 2704 (pg_catalog.pg_type_typname_nsp_index) AccessShareLock\n745064340909039 [Pid 327578] Lock granted (fastpath) 2704 (pg_catalog.pg_type_typname_nsp_index) AccessShareLock\n745064340928115 [Pid 327578] Lock granted (local) 2704 (pg_catalog.pg_type_typname_nsp_index) AccessShareLock (Already hold local 0)\n745064340944601 [Pid 327578] Lock was acquired in 58763 ns\n745064341048196 [Pid 327578] Lock ungranted (fastpath) 2704 (pg_catalog.pg_type_typname_nsp_index) AccessShareLock\n745064341067296 [Pid 327578] Lock ungranted (local) 2704 (pg_catalog.pg_type_typname_nsp_index) AccessShareLock (Hold local 0)\n745064341090013 [Pid 327578] Table close 1247 (pg_catalog.pg_type) AccessShareLock\n745064341111287 [Pid 327578] Lock ungranted (fastpath) 1247 (pg_catalog.pg_type) AccessShareLock\n745064341129580 [Pid 327578] Lock ungranted (local) 1247 (pg_catalog.pg_type) AccessShareLock (Hold local 0)\n745064341157165 [Pid 327578] Table open 1247 (pg_catalog.pg_type) RowExclusiveLock\n745064341173685 [Pid 327578] Lock object 1247 (pg_catalog.pg_type) RowExclusiveLock\n745064341196776 [Pid 327578] Lock granted (fastpath) 1247 (pg_catalog.pg_type) RowExclusiveLock\n745064341215241 [Pid 327578] Lock granted (local) 1247 (pg_catalog.pg_type) RowExclusiveLock (Already hold local 0)\n745064341231900 [Pid 327578] Lock was acquired in 58215 ns\n745064341268528 [Pid 327578] Lock object 2703 (pg_catalog.pg_type_oid_index) RowExclusiveLock\n745064341292333 [Pid 327578] Lock granted (fastpath) 2703 (pg_catalog.pg_type_oid_index) RowExclusiveLock\n745064341341162 [Pid 327578] Lock granted (local) 2703 (pg_catalog.pg_type_oid_index) RowExclusiveLock (Already hold local 0)\n745064341358832 [Pid 327578] Lock was acquired in 90304 ns\n745064341383548 [Pid 327578] Lock object 2704 (pg_catalog.pg_type_typname_nsp_index) RowExclusiveLock\n745064341406525 [Pid 327578] Lock granted (fastpath) 2704 (pg_catalog.pg_type_typname_nsp_index) RowExclusiveLock\n745064341424954 [Pid 327578] Lock granted (local) 2704 (pg_catalog.pg_type_typname_nsp_index) RowExclusiveLock (Already hold local 0)\n745064341441633 [Pid 327578] Lock was acquired in 58085 ns\n745064341627523 [Pid 327578] Lock ungranted (fastpath) 2703 (pg_catalog.pg_type_oid_index) RowExclusiveLock\n745064341646818 [Pid 327578] Lock ungranted (local) 2703 (pg_catalog.pg_type_oid_index) RowExclusiveLock (Hold local 0)\n745064341670307 [Pid 327578] Lock ungranted (fastpath) 2704 (pg_catalog.pg_type_typname_nsp_index) RowExclusiveLock\n745064341688874 [Pid 327578] Lock ungranted (local) 2704 (pg_catalog.pg_type_typname_nsp_index) RowExclusiveLock (Hold local 0)\n745064341718375 [Pid 327578] Table open 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064341735109 [Pid 327578] Lock object 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064341758861 [Pid 327578] Lock granted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064341777284 [Pid 327578] Lock granted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Already hold local 0)\n745064341793917 [Pid 327578] Lock was acquired in 58808 ns\n745064341817673 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064341840607 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064341859012 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064341875436 [Pid 327578] Lock was acquired in 57763 ns\n745064341968082 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064341987340 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064342012766 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342036033 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342054445 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064342070843 [Pid 327578] Lock was acquired in 58077 ns\n745064342158890 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342177887 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064342203087 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342226414 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342245026 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064342261449 [Pid 327578] Lock was acquired in 58362 ns\n745064342345876 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342364857 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064342389842 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342412949 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342431353 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064342488520 [Pid 327578] Lock was acquired in 98678 ns\n745064342575520 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342594610 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064342619914 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342643371 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342662066 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064342678513 [Pid 327578] Lock was acquired in 58599 ns\n745064342770413 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342790169 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064342845082 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342868911 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064342888807 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064342905919 [Pid 327578] Lock was acquired in 60837 ns\n745064342994114 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064343014416 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064343039456 [Pid 327578] Table close 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064343061781 [Pid 327578] Lock ungranted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064343081935 [Pid 327578] Lock ungranted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Hold local 0)\n745064343104591 [Pid 327578] Table open 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064343121705 [Pid 327578] Lock object 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064343145901 [Pid 327578] Lock granted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064343165164 [Pid 327578] Lock granted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Already hold local 0)\n745064343182282 [Pid 327578] Lock was acquired in 60577 ns\n745064343207310 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064343231307 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064343250703 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064343267770 [Pid 327578] Lock was acquired in 60460 ns\n745064343347934 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064343367921 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064343398614 [Pid 327578] Lock object 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock\n745064343423194 [Pid 327578] Lock granted (fastpath) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock\n745064343442803 [Pid 327578] Lock granted (local) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock (Already hold local 0)\n745064343459844 [Pid 327578] Lock was acquired in 61230 ns\n745064343485455 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock\n745064343509461 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock\n745064343528810 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock (Already hold local 0)\n745064343545847 [Pid 327578] Lock was acquired in 60392 ns\n745064343695078 [Pid 327578] Lock ungranted (fastpath) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock\n745064343715321 [Pid 327578] Lock ungranted (local) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock (Hold local 0)\n745064343740180 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock\n745064343759691 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock (Hold local 0)\n745064343782057 [Pid 327578] Table close 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064343803974 [Pid 327578] Lock ungranted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064343823230 [Pid 327578] Lock ungranted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Hold local 0)\n745064343848289 [Pid 327578] Table close 1247 (pg_catalog.pg_type) RowExclusiveLock\n745064343870083 [Pid 327578] Lock ungranted (fastpath) 1247 (pg_catalog.pg_type) RowExclusiveLock\n745064343889205 [Pid 327578] Lock ungranted (local) 1247 (pg_catalog.pg_type) RowExclusiveLock (Hold local 0)\n745064343926948 [Pid 327578] Lock object 2662 (pg_catalog.pg_class_oid_index) RowExclusiveLock\n745064343951401 [Pid 327578] Lock granted (fastpath) 2662 (pg_catalog.pg_class_oid_index) RowExclusiveLock\n745064343970873 [Pid 327578] Lock granted (local) 2662 (pg_catalog.pg_class_oid_index) RowExclusiveLock (Already hold local 0)\n745064343987792 [Pid 327578] Lock was acquired in 60844 ns\n745064344013730 [Pid 327578] Lock object 2663 (pg_catalog.pg_class_relname_nsp_index) RowExclusiveLock\n745064344038107 [Pid 327578] Lock granted (fastpath) 2663 (pg_catalog.pg_class_relname_nsp_index) RowExclusiveLock\n745064344058417 [Pid 327578] Lock granted (local) 2663 (pg_catalog.pg_class_relname_nsp_index) RowExclusiveLock (Already hold local 0)\n745064344075613 [Pid 327578] Lock was acquired in 61883 ns\n745064344101275 [Pid 327578] Lock object 3455 (pg_catalog.pg_class_tblspc_relfilenode_index) RowExclusiveLock\n745064344125438 [Pid 327578] Lock granted (fastpath) 3455 (pg_catalog.pg_class_tblspc_relfilenode_index) RowExclusiveLock\n745064344144823 [Pid 327578] Lock granted (local) 3455 (pg_catalog.pg_class_tblspc_relfilenode_index) RowExclusiveLock (Already hold local 0)\n745064344161792 [Pid 327578] Lock was acquired in 60517 ns\n745064344396301 [Pid 327578] Lock ungranted (fastpath) 2662 (pg_catalog.pg_class_oid_index) RowExclusiveLock\n745064344416716 [Pid 327578] Lock ungranted (local) 2662 (pg_catalog.pg_class_oid_index) RowExclusiveLock (Hold local 0)\n745064344442093 [Pid 327578] Lock ungranted (fastpath) 2663 (pg_catalog.pg_class_relname_nsp_index) RowExclusiveLock\n745064344461627 [Pid 327578] Lock ungranted (local) 2663 (pg_catalog.pg_class_relname_nsp_index) RowExclusiveLock (Hold local 0)\n745064344486604 [Pid 327578] Lock ungranted (fastpath) 3455 (pg_catalog.pg_class_tblspc_relfilenode_index) RowExclusiveLock\n745064344506759 [Pid 327578] Lock ungranted (local) 3455 (pg_catalog.pg_class_tblspc_relfilenode_index) RowExclusiveLock (Hold local 0)\n745064344530484 [Pid 327578] Table open 1249 (pg_catalog.pg_attribute) RowExclusiveLock\n745064344548232 [Pid 327578] Lock object 1249 (pg_catalog.pg_attribute) RowExclusiveLock\n745064344572515 [Pid 327578] Lock granted (fastpath) 1249 (pg_catalog.pg_attribute) RowExclusiveLock\n745064344592394 [Pid 327578] Lock granted (local) 1249 (pg_catalog.pg_attribute) RowExclusiveLock (Already hold local 0)\n745064344609832 [Pid 327578] Lock was acquired in 61600 ns\n745064344638223 [Pid 327578] Lock object 2658 (pg_catalog.pg_attribute_relid_attnam_index) RowExclusiveLock\n745064344662911 [Pid 327578] Lock granted (fastpath) 2658 (pg_catalog.pg_attribute_relid_attnam_index) RowExclusiveLock\n745064344682442 [Pid 327578] Lock granted (local) 2658 (pg_catalog.pg_attribute_relid_attnam_index) RowExclusiveLock (Already hold local 0)\n745064344699381 [Pid 327578] Lock was acquired in 61158 ns\n745064344726938 [Pid 327578] Lock object 2659 (pg_catalog.pg_attribute_relid_attnum_index) RowExclusiveLock\n745064344751669 [Pid 327578] Lock granted (fastpath) 2659 (pg_catalog.pg_attribute_relid_attnum_index) RowExclusiveLock\n745064344771221 [Pid 327578] Lock granted (local) 2659 (pg_catalog.pg_attribute_relid_attnum_index) RowExclusiveLock (Already hold local 0)\n745064344788278 [Pid 327578] Lock was acquired in 61340 ns\n745064345099100 [Pid 327578] Table open 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345117485 [Pid 327578] Lock object 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345142284 [Pid 327578] Lock granted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345161787 [Pid 327578] Lock granted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Already hold local 0)\n745064345178996 [Pid 327578] Lock was acquired in 61511 ns\n745064345204505 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064345228926 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064345248442 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064345265473 [Pid 327578] Lock was acquired in 60968 ns\n745064345393173 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064345413932 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064345438503 [Pid 327578] Table close 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345461015 [Pid 327578] Lock ungranted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345480576 [Pid 327578] Lock ungranted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Hold local 0)\n745064345502818 [Pid 327578] Table open 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345519944 [Pid 327578] Lock object 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345544039 [Pid 327578] Lock granted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345563246 [Pid 327578] Lock granted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Already hold local 0)\n745064345580361 [Pid 327578] Lock was acquired in 60417 ns\n745064345605327 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064345629516 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064345648760 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064345665722 [Pid 327578] Lock was acquired in 60395 ns\n745064345752239 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064345772579 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064345796763 [Pid 327578] Table close 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345822035 [Pid 327578] Lock ungranted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345841159 [Pid 327578] Lock ungranted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Hold local 0)\n745064345863107 [Pid 327578] Table open 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345879945 [Pid 327578] Lock object 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345904002 [Pid 327578] Lock granted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064345923102 [Pid 327578] Lock granted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Already hold local 0)\n745064345939934 [Pid 327578] Lock was acquired in 59989 ns\n745064345964544 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064345988395 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064346007719 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064346024410 [Pid 327578] Lock was acquired in 59866 ns\n745064346111281 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064346131283 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064346155446 [Pid 327578] Table close 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064346177619 [Pid 327578] Lock ungranted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064346196627 [Pid 327578] Lock ungranted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Hold local 0)\n745064346803127 [Pid 327578] Lock ungranted (fastpath) 2658 (pg_catalog.pg_attribute_relid_attnam_index) RowExclusiveLock\n745064346823666 [Pid 327578] Lock ungranted (local) 2658 (pg_catalog.pg_attribute_relid_attnam_index) RowExclusiveLock (Hold local 0)\n745064346848221 [Pid 327578] Lock ungranted (fastpath) 2659 (pg_catalog.pg_attribute_relid_attnum_index) RowExclusiveLock\n745064346867396 [Pid 327578] Lock ungranted (local) 2659 (pg_catalog.pg_attribute_relid_attnum_index) RowExclusiveLock (Hold local 0)\n745064346889677 [Pid 327578] Table close 1249 (pg_catalog.pg_attribute) RowExclusiveLock\n745064346911402 [Pid 327578] Lock ungranted (fastpath) 1249 (pg_catalog.pg_attribute) RowExclusiveLock\n745064346930609 [Pid 327578] Lock ungranted (local) 1249 (pg_catalog.pg_attribute) RowExclusiveLock (Hold local 0)\n745064346954599 [Pid 327578] Table open 1214 (pg_catalog.pg_shdepend) RowExclusiveLock\n745064346971633 [Pid 327578] Lock object 1214 (pg_catalog.pg_shdepend) RowExclusiveLock\n745064347005777 [Pid 327578] Lock granted 1214 (pg_catalog.pg_shdepend) RowExclusiveLock (Requested locks 1)\n745064347024111 [Pid 327578] Lock granted (local) 1214 (pg_catalog.pg_shdepend) RowExclusiveLock (Already hold local 0)\n745064347042353 [Pid 327578] Lock was acquired in 70720 ns\n745064347068452 [Pid 327578] Lock object 1233 (pg_catalog.pg_shdepend_reference_index) AccessShareLock\n745064347099104 [Pid 327578] Lock granted 1233 (pg_catalog.pg_shdepend_reference_index) AccessShareLock (Requested locks 1)\n745064347116884 [Pid 327578] Lock granted (local) 1233 (pg_catalog.pg_shdepend_reference_index) AccessShareLock (Already hold local 0)\n745064347134876 [Pid 327578] Lock was acquired in 66424 ns\n745064347218507 [Pid 327578] Lock ungranted 1233 (pg_catalog.pg_shdepend_reference_index) AccessShareLock (Requested locks 1)\n745064347242474 [Pid 327578] Lock ungranted (local) 1233 (pg_catalog.pg_shdepend_reference_index) AccessShareLock (Hold local 0)\n745064347266550 [Pid 327578] Table close 1214 (pg_catalog.pg_shdepend) RowExclusiveLock\n745064347289588 [Pid 327578] Lock ungranted 1214 (pg_catalog.pg_shdepend) RowExclusiveLock (Requested locks 1)\n745064347311734 [Pid 327578] Lock ungranted (local) 1214 (pg_catalog.pg_shdepend) RowExclusiveLock (Hold local 0)\n745064347336007 [Pid 327578] Table open 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064347353183 [Pid 327578] Lock object 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064347376890 [Pid 327578] Lock granted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064347396366 [Pid 327578] Lock granted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Already hold local 0)\n745064347413477 [Pid 327578] Lock was acquired in 60294 ns\n745064347438596 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064347462497 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064347481886 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064347498752 [Pid 327578] Lock was acquired in 60156 ns\n745064347638679 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064347658780 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064347687516 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064347711680 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064347730837 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Already hold local 0)\n745064347749468 [Pid 327578] Lock was acquired in 61952 ns\n745064347836563 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock\n745064347856592 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) AccessShareLock (Hold local 0)\n745064347885124 [Pid 327578] Lock object 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock\n745064347909388 [Pid 327578] Lock granted (fastpath) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock\n745064347928524 [Pid 327578] Lock granted (local) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock (Already hold local 0)\n745064347945405 [Pid 327578] Lock was acquired in 60281 ns\n745064347971113 [Pid 327578] Lock object 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock\n745064347995140 [Pid 327578] Lock granted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock\n745064348014609 [Pid 327578] Lock granted (local) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock (Already hold local 0)\n745064348102848 [Pid 327578] Lock was acquired in 131735 ns\n745064359396329 [Pid 327578] Lock ungranted (fastpath) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock\n745064359418584 [Pid 327578] Lock ungranted (local) 2673 (pg_catalog.pg_depend_depender_index) RowExclusiveLock (Hold local 0)\n745064359442539 [Pid 327578] Lock ungranted (fastpath) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock\n745064359461367 [Pid 327578] Lock ungranted (local) 2674 (pg_catalog.pg_depend_reference_index) RowExclusiveLock (Hold local 0)\n745064359483081 [Pid 327578] Table close 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064359504077 [Pid 327578] Lock ungranted (fastpath) 2608 (pg_catalog.pg_depend) RowExclusiveLock\n745064359522493 [Pid 327578] Lock ungranted (local) 2608 (pg_catalog.pg_depend) RowExclusiveLock (Hold local 0)\n745064359548580 [Pid 327578] Table close 328332 (public.metrics) NoLock\n745064359566541 [Pid 327578] Table close 1259 (pg_catalog.pg_class) RowExclusiveLock\n745064359587367 [Pid 327578] Lock ungranted (fastpath) 1259 (pg_catalog.pg_class) RowExclusiveLock\n745064359605717 [Pid 327578] Lock ungranted (local) 1259 (pg_catalog.pg_class) RowExclusiveLock (Hold local 0)\n745064359651119 [Pid 327578] Table open 1259 (pg_catalog.pg_class) AccessShareLock\n745064359667961 [Pid 327578] Lock object 1259 (pg_catalog.pg_class) AccessShareLock\n745064359693375 [Pid 327578] Lock granted (fastpath) 1259 (pg_catalog.pg_class) AccessShareLock\n745064359714827 [Pid 327578] Lock granted (local) 1259 (pg_catalog.pg_class) AccessShareLock (Already hold local 0)\n745064359732703 [Pid 327578] Lock was acquired in 64742 ns\n745064359755347 [Pid 327578] Lock object 2662 (pg_catalog.pg_class_oid_index) AccessShareLock\n745064359778100 [Pid 327578] Lock granted (fastpath) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock\n745064359796247 [Pid 327578] Lock granted (local) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock (Already hold local 0)\n745064359812617 [Pid 327578] Lock was acquired in 57270 ns\n745064359909910 [Pid 327578] Lock ungranted (fastpath) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock\n745064359929042 [Pid 327578] Lock ungranted (local) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock (Hold local 0)\n745064359952201 [Pid 327578] Table close 1259 (pg_catalog.pg_class) AccessShareLock\n745064359973399 [Pid 327578] Lock ungranted (fastpath) 1259 (pg_catalog.pg_class) AccessShareLock\n745064359991320 [Pid 327578] Lock ungranted (local) 1259 (pg_catalog.pg_class) AccessShareLock (Hold local 0)\n745064360036095 [Pid 327578] Table open 1249 (pg_catalog.pg_attribute) AccessShareLock\n745064360052741 [Pid 327578] Lock object 1249 (pg_catalog.pg_attribute) AccessShareLock\n745064360075910 [Pid 327578] Lock granted (fastpath) 1249 (pg_catalog.pg_attribute) AccessShareLock\n745064360093944 [Pid 327578] Lock granted (local) 1249 (pg_catalog.pg_attribute) AccessShareLock (Already hold local 0)\n745064360110225 [Pid 327578] Lock was acquired in 57484 ns\n745064360132111 [Pid 327578] Lock object 2659 (pg_catalog.pg_attribute_relid_attnum_index) AccessShareLock\n745064360154727 [Pid 327578] Lock granted (fastpath) 2659 (pg_catalog.pg_attribute_relid_attnum_index) AccessShareLock\n745064360172921 [Pid 327578] Lock granted (local) 2659 (pg_catalog.pg_attribute_relid_attnum_index) AccessShareLock (Already hold local 0)\n745064360189385 [Pid 327578] Lock was acquired in 57274 ns\n745064360354543 [Pid 327578] Lock ungranted (fastpath) 2659 (pg_catalog.pg_attribute_relid_attnum_index) AccessShareLock\n745064360373938 [Pid 327578] Lock ungranted (local) 2659 (pg_catalog.pg_attribute_relid_attnum_index) AccessShareLock (Hold local 0)\n745064360396537 [Pid 327578] Table close 1249 (pg_catalog.pg_attribute) AccessShareLock\n745064360417835 [Pid 327578] Lock ungranted (fastpath) 1249 (pg_catalog.pg_attribute) AccessShareLock\n745064360436021 [Pid 327578] Lock ungranted (local) 1249 (pg_catalog.pg_attribute) AccessShareLock (Hold local 0)\n745064360483980 [Pid 327578] Lock object 328332 (public.metrics) AccessExclusiveLock\n745064360606079 [Pid 327578] Lock granted 328332 (public.metrics) AccessExclusiveLock (Requested locks 1)\n745064360623446 [Pid 327578] Lock granted (local) 328332 (public.metrics) AccessExclusiveLock (Already hold local 0)\n745064360649586 [Pid 327578] Lock was acquired in 165606 ns\n745064360728965 [Pid 327578] Table open 328332 (public.metrics) AccessExclusiveLock\n745064360745603 [Pid 327578] Lock object 328332 (public.metrics) AccessExclusiveLock\n745064360766604 [Pid 327578] Lock granted (local) 328332 (public.metrics) AccessExclusiveLock (Already hold local 1)\n745064360781540 [Pid 327578] Lock was acquired in 35937 ns\n745064360803960 [Pid 327578] Table close 328332 (public.metrics) NoLock\n745064360915669 [Pid 327578] Table open 1259 (pg_catalog.pg_class) AccessShareLock\n745064360932430 [Pid 327578] Lock object 1259 (pg_catalog.pg_class) AccessShareLock\n745064360955869 [Pid 327578] Lock granted (fastpath) 1259 (pg_catalog.pg_class) AccessShareLock\n745064360974141 [Pid 327578] Lock granted (local) 1259 (pg_catalog.pg_class) AccessShareLock (Already hold local 0)\n745064360990725 [Pid 327578] Lock was acquired in 58295 ns\n745064361012714 [Pid 327578] Lock object 2662 (pg_catalog.pg_class_oid_index) AccessShareLock\n745064361035492 [Pid 327578] Lock granted (fastpath) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock\n745064361053701 [Pid 327578] Lock granted (local) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock (Already hold local 0)\n745064361070112 [Pid 327578] Lock was acquired in 57398 ns\n745064361163634 [Pid 327578] Lock ungranted (fastpath) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock\n745064361182887 [Pid 327578] Lock ungranted (local) 2662 (pg_catalog.pg_class_oid_index) AccessShareLock (Hold local 0)\n745064361206214 [Pid 327578] Table close 1259 (pg_catalog.pg_class) AccessShareLock\n745064361227633 [Pid 327578] Lock ungranted (fastpath) 1259 (pg_catalog.pg_class) AccessShareLock\n745064361245881 [Pid 327578] Lock ungranted (local) 1259 (pg_catalog.pg_class) AccessShareLock (Hold local 0)\n745064361287525 [Pid 327578] Table open 1259 (pg_catalog.pg_class) AccessShareLock\n745064361331732 [Pid 327578] Lock object 1259 (pg_catalog.pg_class) AccessShareLock\n745064361356607 [Pid 327578] Lock granted (fastpath) 1259 (pg_catalog.pg_class) AccessShareLock\n745064361375138 [Pid 327578] Lock granted (local) 1259 (pg_catalog.pg_class) AccessShareLock (Already hold local 0)\n745064361391959 [Pid 327578] Lock was acquired in 60227 ns\n745064361424521 [Pid 327578] Table close 1259 (pg_catalog.pg_class) AccessShareLock\n745064361445624 [Pid 327578] Lock ungranted (fastpath) 1259 (pg_catalog.pg_class) AccessShareLock\n745064361463789 [Pid 327578] Lock ungranted (local) 1259 (pg_catalog.pg_class) AccessShareLock (Hold local 0)\n745064361535429 [Pid 327578] Table open 1259 (pg_catalog.pg_class) AccessShareLock\n745064361552253 [Pid 327578] Lock object 1259 (pg_catalog.pg_class) AccessShareLock\n745064361575061 [Pid 327578] Lock granted (fastpath) 1259 (pg_catalog.pg_class) AccessShareLock\n745064361593224 [Pid 327578] Lock granted (local) 1259 (pg_catalog.pg_class) AccessShareLock (Already hold local 0)\n745064361609584 [Pid 327578] Lock was acquired in 57331 ns\n745064361631520 [Pid 327578] Lock object 2663 (pg_catalog.pg_class_relname_nsp_index) AccessShareLock\n745064361654381 [Pid 327578] Lock granted (fastpath) 2663 (pg_catalog.pg_class_relname_nsp_index) AccessShareLock\n745064361672562 [Pid 327578] Lock granted (local) 2663 (pg_catalog.pg_class_relname_nsp_index) AccessShareLock (Already hold local 0)\n745064361688805 [Pid 327578] Lock was acquired in 57285 ns\n745064361788882 [Pid 327578] Lock ungranted (fastpath) 2663 (pg_catalog.pg_class_relname_nsp_index) AccessShareLock\n745064361808199 [Pid 327578] Lock ungranted (local) 2663 (pg_catalog.pg_class_relname_nsp_index) AccessShareLock (Hold local 0)\n745064361831553 [Pid 327578] Table close 1259 (pg_catalog.pg_class) AccessShareLock\n745064361852740 [Pid 327578] Lock ungranted (fastpath) 1259 (pg_catalog.pg_class) AccessShareLock\n745064361870841 [Pid 327578] Lock ungranted (local) 1259 (pg_catalog.pg_class) AccessShareLock (Hold local 0)\n745064362332644 [Pid 327578] Transaction commit\n745064368169138 [Pid 327578] Lock ungranted (local) 2615 (pg_catalog.pg_namespace) AccessShareLock (Hold local 2)\n745064368193137 [Pid 327578] Lock ungranted (local) 328332 (public.metrics) AccessExclusiveLock (Hold local 2)\n745064368236259 [Pid 327578] Lock ungranted 328332 (public.metrics) AccessExclusiveLock (Requested locks 1)\n745064368260426 [Pid 327578] Lock ungranted 2615 (pg_catalog.pg_namespace) AccessShareLock (Requested locks 1)\n745064368747863 [Pid 327578] Query done\n```\n</details>\n\n\nStatistics\n\n```\nLock statistics:\n================\n\nLocks per oid\n+----------------------------------------------+----------+------------------------------+\n|                  Lock Name                   | Requests | Total Lock Request Time (ns) |\n+----------------------------------------------+----------+------------------------------+\n|     pg_catalog.pg_depend_reference_index     |    20    |           1174663            |\n|             pg_catalog.pg_depend             |    8     |            456525            |\n|              pg_catalog.pg_type              |    5     |            282986            |\n|     pg_catalog.pg_type_typname_nsp_index     |    4     |            229317            |\n|         pg_catalog.pg_type_oid_index         |    4     |            300239            |\n|             pg_catalog.pg_class              |    3     |            180540            |\n|        pg_catalog.pg_class_oid_index         |    3     |            172549            |\n|     pg_catalog.pg_depend_depender_index      |    3     |            171186            |\n|    pg_catalog.pg_class_relname_nsp_index     |    2     |            114311            |\n|           pg_catalog.pg_attribute            |    2     |            113041            |\n|  pg_catalog.pg_attribute_relid_attnum_index  |    2     |            113299            |\n|                public.metrics                |    2     |            223162            |\n| pg_catalog.pg_class_tblspc_relfilenode_index |    1     |            56426             |\n|  pg_catalog.pg_attribute_relid_attnam_index  |    1     |            57238             |\n|            pg_catalog.pg_shdepend            |    1     |            65878             |\n|    pg_catalog.pg_shdepend_reference_index    |    1     |            63127             |\n+----------------------------------------------+----------+------------------------------+\n\nLock types\n+---------------------+---------------------------+\n|      Lock Type      | Number of requested locks |\n+---------------------+---------------------------+\n|   AccessShareLock   |             32            |\n|   RowExclusiveLock  |             28            |\n| AccessExclusiveLock |             2             |\n+---------------------+---------------------------+\n```\n\n## Filter Trace Events\n`pg_lock_tracer` traces per default all supported events. However, often only certain events are required for the analysis (e.g., _which tables are opened?_). The event tracing can be restricted to certain events using the `-t <EVENT1> <EVENT2>` parameter. The following events are currently supported:\n\n| Event          | Description                                                                                          |\n|----------------|------------------------------------------------------------------------------------------------------|\n| `TRANSACTION`  | Transactions related events (e.g., `StartTransaction`, `CommitTransaction`, `DeadLockReport`)        |\n| `QUERY`        | The executed queries (e.g., `exec_simple_query`)                                                     |\n| `TABLE`        | Table open and close events (e.g., `table_open`, `table_openrv`, `table_close`)                      |\n| `LOCK`         | Lock events (e.g., `LockRelationOid`, `UnlockRelationOid`, `GrantLock`, `FastPathGrantRelationLock`) |\n| `INVALIDATION` | Processing of cache invalidation messages (e.g., `AcceptInvalidationMessages`)                       |\n| `ERROR`        | Error related events (e.g., `bpf_errstart`)                                                          |\n\n```\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_2_DEBUG/bin/postgres -p 2287921 -r 2287921:psql://jan@localhost/test2 --statistics -t TABLE\n[...]\n4111321097620311 [Pid 2290711] Table open (by range value) .metric_name_local AccessShareLock\n4111321097626817 [Pid 2287921] Table close 343035 (public.metric_name_local) NoLock\n4111321097722307 [Pid 2287921] Table open 3079 (pg_catalog.pg_extension) AccessShareLock\n4111321097877109 [Pid 2287921] Table close 3079 (pg_catalog.pg_extension) AccessShareLock\n4111321097904906 [Pid 2287921] Table open 3079 (pg_catalog.pg_extension) AccessShareLock\n4111321098012011 [Pid 2287921] Table close 3079 (pg_catalog.pg_extension) AccessShareLock\n4111321098049134 [Pid 2287921] Table open 343035 (public.metric_name_local) NoLock\n4111321098072567 [Pid 2287921] Table close 343035 (public.metric_name_local) NoLock\n4111321098089922 [Pid 2287921] Table open 343035 (public.metric_name_local) NoLock\n4111321098116394 [Pid 2287921] Table close 343035 (public.metric_name_local) NoLock\n4111321098350309 [Pid 2287921] Table open 343035 (public.metric_name_local) NoLock\n4111321098484761 [Pid 2287921] Table close 343035 (public.metric_name_local) NoLock\n4111321098795235 [Pid 2287921] Table open 343035 (public.metric_name_local) NoLock\n4111321098931302 [Pid 2287921] Table close 343035 (public.metric_name_local) NoLock\n```\n\n## Stack Traces\n\nIt is sometimes necessary to determine where in the source code a particular lock is requested. For this purpose, the option `-s <Lock Event>` can be used. In addition to the traces, stack traces are now also shown.\n\nFor example, by specifying `-s LOCK` a stack trace is generated and shown on each lock event. The following example shows where the lock for `pg_catalog.pg_extension` was requested.\n\n```\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_2_DEBUG/bin/postgres -p 1051967 -r 1051967:sql://jan@localhost/test2 -s LOCK\n[...]\n1990162746005798 [Pid 1051967] Lock object 3079 (pg_catalog.pg_extension) AccessShareLock\n\tLockRelationOid+0x0 [postgres]\n\ttable_open+0x1d [postgres]\n\tparse_analyze+0xed [postgres]\n\tpg_analyze_and_rewrite+0x49 [postgres]\n\texec_simple_query+0x2db [postgres]\n\tPostgresMain+0x833 [postgres]\n\tExitPostmaster+0x0 [postgres]\n\tBackendStartup+0x1b1 [postgres]\n\tServerLoop+0x2d9 [postgres]\n\tPostmasterMain+0x1286 [postgres]\n\tstartup_hacks+0x0 [postgres]\n\t__libc_start_main+0xea [libc-2.31.so]\n\t[unknown]\n[...]\n```\n\n### Animated Lock Graphs\nSee the content of the [examples](examples/) directory for examples.\n\n# pg_lw_lock_tracer\n\n`pg_lw_lock_trace` allows to trace lightweight locks ([LWLocks](https://github.com/postgres/postgres/blob/c8e1ba736b2b9e8c98d37a5b77c4ed31baf94147/src/backend/storage/lmgr/lwlock.c)) in a PostgreSQL process via _Userland Statically Defined Tracing_ (USDT).\n\n## 🧪 Usage Examples\n```\n# Trace the LW locks of the PID 1234\npg_lw_lock_tracer -p 1234\n\n# Trace the LW locks of the PIDs 1234 and 5678\npg_lw_lock_tracer -p 1234 -p 5678\n\n# Trace the LW locks of the PID 1234 and be verbose\npg_lw_lock_tracer -p 1234 -v\n\n# Trace the LW locks of the PID 1234 and collect statistics\npg_lw_lock_tracer -p 1234 -v --statistics\n```\n\n## Example output\n\nSQL Query: `insert into test values(2);`\n\nCLI: `sudo pg_lw_lock_tracer -p 1698108 --statistics`\n\nTracer output:\n\n```\n2904552881615298 [Pid 1704367] Acquired lock LockFastPath (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904552881673849 [Pid 1704367] Unlock LockFastPath\n2904552881782910 [Pid 1704367] Acquired lock ProcArray (mode LW_SHARED) / LWLockAcquire()\n2904552881803614 [Pid 1704367] Unlock ProcArray\n2904552881865272 [Pid 1704367] Acquired lock LockFastPath (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904552881883641 [Pid 1704367] Unlock LockFastPath\n[...]\n```\n\n<details>\n  <summary>Full Output</summary>\n\n```\n===> Ready to trace\n2904552881615298 [Pid 1704367] Acquired lock LockFastPath (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904552881673849 [Pid 1704367] Unlock LockFastPath\n2904552881782910 [Pid 1704367] Acquired lock ProcArray (mode LW_SHARED) / LWLockAcquire()\n2904552881803614 [Pid 1704367] Unlock ProcArray\n2904552881865272 [Pid 1704367] Acquired lock LockFastPath (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904552881883641 [Pid 1704367] Unlock LockFastPath\n2904552882095131 [Pid 1704367] Acquired lock ProcArray (mode LW_SHARED) / LWLockAcquire()\n2904552882114171 [Pid 1704367] Unlock ProcArray\n2904552882225372 [Pid 1704367] Acquired lock XidGen (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904552882246673 [Pid 1704367] Unlock XidGen\n2904552882270279 [Pid 1704367] Acquired lock LockManager (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904552882296782 [Pid 1704367] Unlock LockManager\n2904552882335466 [Pid 1704367] Acquired lock BufferMapping (mode LW_SHARED) / LWLockAcquire()\n2904552882358198 [Pid 1704367] Unlock BufferMapping\n2904552882379951 [Pid 1704367] Acquired lock BufferContent (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904552882415333 [Pid 1704367] Acquired lock WALInsert (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904552882485459 [Pid 1704367] Unlock WALInsert\n2904552882506167 [Pid 1704367] Unlock BufferContent\n2904552882590752 [Pid 1704367] Acquired lock WALInsert (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904552882611656 [Pid 1704367] Unlock WALInsert\n2904552882638194 [Pid 1704367] Wait for WALWrite\n2904554401202251 [Pid 1704367] Wait for WALWrite lock took 1518564057 ns\n2904554401222926 [Pid 1704367] Waited but not acquired WALWrite (mode LW_EXCLUSIVE) / LWLockConditionalAcquire()\n2904554401234504 [Pid 1704367] Acquired lock WALWrite (mode LW_EXCLUSIVE) / LWLockConditionalAcquire()\n2904554404873664 [Pid 1704367] Unlock WALWrite\n2904554404928035 [Pid 1704367] Acquired lock XactSLRU (mode LW_EXCLUSIVE) / LWLockConditionalAcquire()\n2904554404950334 [Pid 1704367] Unlock XactSLRU\n2904554404972224 [Pid 1704367] Acquired lock ProcArray (mode LW_EXCLUSIVE) / LWLockConditionalAcquire()\n2904554404993887 [Pid 1704367] Unlock ProcArray\n2904554405022734 [Pid 1704367] Acquired lock LockFastPath (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904554405038888 [Pid 1704367] Unlock LockFastPath\n2904554405059788 [Pid 1704367] Acquired lock LockFastPath (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904554405088143 [Pid 1704367] Unlock LockFastPath\n2904554405106194 [Pid 1704367] Acquired lock LockManager (mode LW_EXCLUSIVE) / LWLockAcquire()\n2904554405145780 [Pid 1704367] Unlock LockManager\n2904554405622791 [Pid 1704367] Acquired lock PgStatsData (mode LW_EXCLUSIVE) / LWLockConditionalAcquire()\n2904554405640885 [Pid 1704367] Unlock PgStatsData\n2904554405665146 [Pid 1704367] Acquired lock PgStatsData (mode LW_EXCLUSIVE) / LWLockConditionalAcquire()\n2904554405682599 [Pid 1704367] Unlock PgStatsData\n2904554405704514 [Pid 1704367] Acquired lock PgStatsData (mode LW_EXCLUSIVE) / LWLockConditionalAcquire()\n2904554405720734 [Pid 1704367] Unlock PgStatsData\n2904554405737937 [Pid 1704367] Acquired lock PgStatsData (mode LW_EXCLUSIVE) / LWLockConditionalAcquire()\n2904554405755387 [Pid 1704367] Unlock PgStatsData\n```\n</details>\n\nStatistics\n\n```\nLock statistics:\n================\n\nLocks per tranche\n+---------------+----------+--------------------------+------------------------+-------------------------------+-----------------------------+-------+----------------+\n|    Tranche    | Acquired | AcquireOrWait (Acquired) | AcquireOrWait (Waited) | ConditionalAcquire (Acquired) | ConditionalAcquire (Failed) | Waits | Wait time (ns) |\n+---------------+----------+--------------------------+------------------------+-------------------------------+-----------------------------+-------+----------------+\n| BufferContent |    1     |            0             |           0            |               0               |              0              |   0   |       0        |\n| BufferMapping |    1     |            0             |           0            |               0               |              0              |   0   |       0        |\n|  LockFastPath |    4     |            0             |           0            |               0               |              0              |   0   |       0        |\n|  LockManager  |    2     |            0             |           0            |               0               |              0              |   0   |       0        |\n|  PgStatsData  |    0     |            0             |           0            |               4               |              0              |   0   |       0        |\n|   ProcArray   |    2     |            0             |           0            |               1               |              0              |   0   |       0        |\n|   WALInsert   |    2     |            0             |           0            |               0               |              0              |   0   |       0        |\n|    WALWrite   |    0     |            1             |           1            |               0               |              0              |   1   |   1518564057   |\n|    XactSLRU   |    0     |            0             |           0            |               1               |              0              |   0   |       0        |\n|     XidGen    |    1     |            0             |           0            |               0               |              0              |   0   |       0        |\n+---------------+----------+--------------------------+------------------------+-------------------------------+-----------------------------+-------+----------------+\n\nLocks per type\n+--------------+----------+\n|  Lock type   | Requests |\n+--------------+----------+\n| LW_EXCLUSIVE |    18    |\n|  LW_SHARED   |    3     |\n+--------------+----------+\n```\n\n# pg_row_lock_tracer\n\n`pg_row_lock_tracer` allows to trace row locks (see the PostgreSQL [documentation](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS)) of a PostgreSQL process using _eBPF_ and _UProbes_\n\n## 🧪 Usage Examples\n```\n# Trace the row locks of the given PostgreSQL binary\npg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres\n\n# Trace the row locks of the PID 1234\npg_row_lock_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres\n\n# Trace the row locks of the PID 1234 and 5678\npg_row_lock_tracer -p 1234 -p 5678 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres\n\n# Trace the row locks of the PID 1234 and be verbose\npg_row_lock_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres -v\n\n# Trace the row locks and show statistics\npg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres --statistics\n```\n\n## Example output\n\nSQL Query: `SELECT * FROM temperature FOR UPDATE;`\n\nCLI: `sudo pg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres --statistics`\n\n\nTracer output:\n\n```\n[...]\n2783502701862408 [Pid 2604491] LOCK_TUPLE_END TM_OK in 13100 ns\n2783502701877081 [Pid 2604491] LOCK_TUPLE (Tablespace 1663 database 305234 relation 313419) - (Block and offset 7 143) - LOCK_TUPLE_EXCLUSIVE LOCK_WAIT_BLOCK\n2783502701972367 [Pid 2604491] LOCK_TUPLE_END TM_OK in 95286 ns\n2783502701988387 [Pid 2604491] LOCK_TUPLE (Tablespace 1663 database 305234 relation 313419) - (Block and offset 7 144) - LOCK_TUPLE_EXCLUSIVE LOCK_WAIT_BLOCK\n2783502702001690 [Pid 2604491] LOCK_TUPLE_END TM_OK in 13303 ns\n2783502702016387 [Pid 2604491] LOCK_TUPLE (Tablespace 1663 database 305234 relation 313419) - (Block and offset 7 145) - LOCK_TUPLE_EXCLUSIVE LOCK_WAIT_BLOCK\n2783502702029375 [Pid 2604491] LOCK_TUPLE_END TM_OK in 12988 ns\n^C\nLock statistics:\n================\n\nUsed wait policies:\n+---------+-----------------+----------------+-----------------+\n|   PID   | LOCK_WAIT_BLOCK | LOCK_WAIT_SKIP | LOCK_WAIT_ERROR |\n+---------+-----------------+----------------+-----------------+\n| 2604491 |       1440      |       0        |        0        |\n+---------+-----------------+----------------+-----------------+\n\nLock modes:\n+---------+---------------------+------------------+---------------------------+----------------------+\n|   PID   | LOCK_TUPLE_KEYSHARE | LOCK_TUPLE_SHARE | LOCK_TUPLE_NOKEYEXCLUSIVE | LOCK_TUPLE_EXCLUSIVE |\n+---------+---------------------+------------------+---------------------------+----------------------+\n| 2604491 |          0          |        0         |             0             |         1440         |\n+---------+---------------------+------------------+---------------------------+----------------------+\n\nLock results:\n+---------+-------+--------------+-----------------+------------+------------+------------------+---------------+\n|   PID   | TM_OK | TM_INVISIBLE | TM_SELFMODIFIED | TM_UPDATED | TM_DELETED | TM_BEINGMODIFIED | TM_WOULDBLOCK |\n+---------+-------+--------------+-----------------+------------+------------+------------------+---------------+\n| 2604491 |  1440 |      0       |        0        |     0      |     0      |        0         |       0       |\n+---------+-------+--------------+-----------------+------------+------------+------------------+---------------+\n```\n\n# pg_spinlock_delay_tracer\n`pg_spinlock_delay_tracer` allows tracing spinlock delays in a PostgreSQL process. Spin locks are used in PostgreSQL to protect short critical sections in the code. If another process already holds a spinlock, the requesting process will repeatedly check (i.e., \"spin\") until the lock becomes available. If the lock is held for a longer period, PostgreSQL performs a [\"spin delay\"](https://github.com/postgres/postgres/blob/0c8e082fba8d36434552d3d7800abda54acafd57/src/backend/storage/lmgr/s_lock.c#L106) and yields the CPU for a short time to avoid busy-waiting. Such delays are reported via the `pg_spinlock_delay_tracer`. For each delay, it prints the content of the `SpinDelayStatus` structure, which contains information about the number of spins, delays, and the current delay time. Additionally, the function name and source code location where the spin delay occurred are reported.\n\n## 🧪 Usage Examples\n```\n# Trace the spinlock delays of the given PostgreSQL binary\npg_spinlock_delay_tracer -x /home/jan/postgresql-sandbox/bin/REL_17_1_DEBUG/bin/postgres\n\n# Trace the spinlock delays of the PID 1234\npg_spinlock_delay_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_17_1_DEBUG/bin/postgres\n```\n\n## Example output\nTo reproduce a spinlock delay, follow these steps to simulate a delay at the WAL insert position. First, start two different sessions connected to the same database. Then, create two tables:\n\n```sql\nCREATE TABLE mydata1 (id INT);\nCREATE TABLE mydata2 (id INT);\n```\n\nNext, open a debugger and set a breakpoint in the function `ReserveXLogInsertLocation` after the spin lock `SpinLockAcquire(&Insert->insertpos_lck);` is acquired. Afterward, start the `pg_spinlock_delay_tracer` and perform two inserts in the two different sessions:\n\n```\n# Session 1\nINSERT INTO mydata1 VALUES(1);\n# Session 2\nINSERT INTO mydata2 VALUES(2);\n```\n\nNote: Two different tables are used to prevent both sessions from trying to lock the same buffer and waiting for each other on a different lock.\n\nThe debugger should stop in the first session at the breakpoint. Furthermore, the pg_spinlock_delay_tracer should report spinlock delays in the second session, as the first session holds the spinlock for a longer period.\n\n```\npg_spinlock_delay_tracer -x /home/jan/postgresql-sandbox/bin/REL_17_1_DEBUG/bin/postgres\n[...]\n13180680737869452 [Pid 1864403] SpinDelay spins=996 delays=939 cur_delay=566086 at ReserveXLogInsertLocation, xlog.c:1132\n13180680737874986 [Pid 1864403] SpinDelay spins=997 delays=939 cur_delay=566086 at ReserveXLogInsertLocation, xlog.c:1132\n13180680737880522 [Pid 1864403] SpinDelay spins=998 delays=939 cur_delay=566086 at ReserveXLogInsertLocation, xlog.c:1132\n13180680737886009 [Pid 1864403] SpinDelay spins=999 delays=939 cur_delay=566086 at ReserveXLogInsertLocation, xlog.c:1132\n13180681304189362 [Pid 1864403] SpinDelay spins=0 delays=940 cur_delay=661655 at ReserveXLogInsertLocation, xlog.c:1132\n13180681304227806 [Pid 1864403] SpinDelay spins=1 delays=940 cur_delay=661655 at ReserveXLogInsertLocation, xlog.c:1132\n13180681304241759 [Pid 1864403] SpinDelay spins=2 delays=940 cur_delay=661655 at ReserveXLogInsertLocation, xlog.c:1132\n13180681304255150 [Pid 1864403] SpinDelay spins=3 delays=940 cur_delay=661655 at ReserveXLogInsertLocation, xlog.c:1132\n[...]\n```\n\n# Additional Information\n\n## Installation\n\nThe PostgreSQL lock tracing tools are available as a Python package. These tools depend on the Python package for BPF. Unfortunately, this package is currently not available via `pip` (the Python package manager). Therefore, the package of the Linux distribution needs to be installed to provide this dependency. On Debian and Ubuntu, this can be done by executing the following command:\n\n```shell\napt install python3-bpfcc\n```\n\nThe tracing tools can be installed system-wide or in a dedicated [virtual environment](https://docs.python.org/3/library/venv.html). To create and install the tools in such a virtual environment, the following steps must be performed. To install the tools system-wide, these steps can be skipped.\n\n```shell\ncd <installation directory>\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Copy the distribution Python BCC packages into this environment\ncp -av /usr/lib/python3/dist-packages/bcc* $(python -c \"import sysconfig; print(sysconfig.get_path('platlib'))\")\n```\n\nNow, the tracing tools can be installed directly via `pip` by executing:\n\n```shell\npip install pg-lock-tracer\n```\n\nThe tools are now installed and can be invoked by calling `pg_lock_tracer` or `pg_lw_lock_tracer`.\n\nIf you want to install the latest development snapshot and development dependencies of the tools, the following commands need to be executed:\n\n```shell\npip install -r requirements_dev.txt\npip install git+https://github.com/jnidzwetzki/pg-lock-tracer\n```\n\n## PostgreSQL Build\nThe software is tested with PostgreSQL versions 14, 15, 16, 17, and 18. In order to be able to attach the _uprobes_ to the functions, they should not to be optimized away (e.g., inlined) during the compilation of PostgreSQL. Otherwise errors like `Unable to locate function XXX` will occur when `pg_lock_tracer` is started.\n\nIt is recommended to compile PostgreSQL with the following CFLAGS: `CFLAGS=\"-ggdb -Og -g3 -fno-omit-frame-pointer\"`. \n\n`pg_lw_lock_trace` uses [USDT probes](https://www.postgresql.org/docs/current/dynamic-trace.html). Therefore, PostgreSQL has to be compiled with `--enable-dtrace` to use this script. \n"
  },
  {
    "path": "examples/create_table_trace.html",
    "content": "\n<!DOCTYPE html>\n<meta charset=\"utf-8\">\n<body>\n<script src=\"https://d3js.org/d3.v7.js\"></script>\n<script src=\"https://unpkg.com/@hpcc-js/wasm@2/dist/graphviz.umd.js\"></script>\n<script src=\"https://unpkg.com/d3-graphviz@5/build/d3-graphviz.js\"></script>\n\n<style>\n.frame_div {\n   display: inline-block;\n}\n\n#frame_control {\n   background-color: lightgray;\n   height: 24px;\n   margin-bottom: 5px;\n   padding-left: 5px;\n}\n\n#pause_control {\n   padding-left: 20px;\n}\n\ninput, output {\n  vertical-align: middle;\n}\n</style>\n<div id=\"frame_control\">\n  Frame <input type=\"range\" id=\"active_frame_slider\" min=\"0\" max=\"100\" value=\"0\" oninput=\"updateSlider(this.value);\" onchange=\"render();\">\n  <div id=\"frames\" class=\"frame_div\">\n     (<div id=\"cur_frame\" class=\"frame_div\"></div> of <div id=\"total_frame\" class=\"frame_div\"></div>)\n  </div>\n  <div id=\"pause_control\" class=\"frame_div\">\n    <input type=\"checkbox\" id=\"render_active\" name=\"render_active\" value=\"active\" checked onclick=\"render();\">\n     <label for=\"render_active\" style=\"vertical-align: bottom;\">&#9658; Play</label>\n    </input>\n  </div>\n</div>\n\n<div id=\"graph\" style=\"text-align: center;\"></div>\n\n<script>\nvar dotIndex = 0;\n\nvar graphviz = d3.select(\"#graph\").graphviz()\n    .attributer(attributer)\n    .transition(function () {\n        return d3.transition(\"main\")\n            .ease(d3.easeLinear)\n            .delay(500)\n            .duration(1500);\n    })\n    .logEvents(true)\n    .engine('circo')\n    .on(\"initEnd\", render);\n\nfunction render() {\n    var dotLines = dots[dotIndex];\n    var dot = dotLines.join('');\n    graphviz\n        .renderDot(dot)\n        .on(\"end\", function () {\n            if (! document.getElementById('render_active').checked) {\n                return;\n            }\n            dotIndex = (dotIndex + 1) % dots.length;\n            updateFrames();\n            document.getElementById(\"active_frame_slider\").value = dotIndex;\n            render();\n        })\n        .zoom(true);\n}\n\nfunction updateFrames() {\n    document.getElementById(\"cur_frame\").innerHTML = dotIndex;\n    document.getElementById(\"total_frame\").innerHTML = dots.length;\n}\n\nfunction updateSlider(newValue) {\n    dotIndex = Number(newValue);\n    updateFrames();\n}\n\nfunction initSlider() {\n    document.getElementById(\"active_frame_slider\").value = dotIndex;\n    document.getElementById(\"active_frame_slider\").max = dots.length;\n}\n\nfunction attributer(datum, index, nodes) {\n    marginWidth = 20; // to avoid scrollbars\n    marginHeight = 40;\n    var selection = d3.select(this);\n    if (datum.tag == \"svg\") {\n        var width = window.innerWidth;\n        var height = window.innerHeight;\n        datum.attributes.width = width - marginWidth;\n        datum.attributes.height = height - marginHeight;\n    }\n}\n\n\nvar dots = [\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_relname_nsp_index\" [label=\"pg_catalog.pg_class_relname_\\nnsp_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_relname_nsp_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_typname_nsp_index\" [label=\"pg_catalog.pg_type_typname_\\nnsp_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_typname_nsp_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_oid_index\" [label=\"pg_catalog.pg_class_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_oid_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_oid_index\" [label=\"pg_catalog.pg_type_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_oid_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_oid_index\" [label=\"pg_catalog.pg_type_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_oid_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_oid_index\" [label=\"pg_catalog.pg_type_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_oid_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_oid_index\" [label=\"pg_catalog.pg_type_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_typname_nsp_index\" [label=\"pg_catalog.pg_type_typname_\\nnsp_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_oid_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_typname_nsp_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_typname_nsp_index\" [label=\"pg_catalog.pg_type_typname_\\nnsp_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_typname_nsp_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_depender_index\" [label=\"pg_catalog.pg_depend_\\ndepender_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_depender_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_depender_index\" [label=\"pg_catalog.pg_depend_\\ndepender_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_depender_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_typname_nsp_index\" [label=\"pg_catalog.pg_type_typname_\\nnsp_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_typname_nsp_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_oid_index\" [label=\"pg_catalog.pg_type_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_oid_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_oid_index\" [label=\"pg_catalog.pg_type_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_typname_nsp_index\" [label=\"pg_catalog.pg_type_typname_\\nnsp_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_oid_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_typname_nsp_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type_typname_nsp_index\" [label=\"pg_catalog.pg_type_typname_\\nnsp_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type_typname_nsp_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_depender_index\" [label=\"pg_catalog.pg_depend_\\ndepender_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_depender_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_depender_index\" [label=\"pg_catalog.pg_depend_\\ndepender_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_depender_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_type\" [label=\"pg_catalog.pg_type\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_type\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_oid_index\" [label=\"pg_catalog.pg_class_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_oid_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_oid_index\" [label=\"pg_catalog.pg_class_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_relname_nsp_index\" [label=\"pg_catalog.pg_class_relname_\\nnsp_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_oid_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_relname_nsp_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_oid_index\" [label=\"pg_catalog.pg_class_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_relname_nsp_index\" [label=\"pg_catalog.pg_class_relname_\\nnsp_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_tblspc_relfilenode_index\" [label=\"pg_catalog.pg_class_tblspc_\\nrelfilenode_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_oid_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_relname_nsp_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_tblspc_relfilenode_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_relname_nsp_index\" [label=\"pg_catalog.pg_class_relname_\\nnsp_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_tblspc_relfilenode_index\" [label=\"pg_catalog.pg_class_tblspc_\\nrelfilenode_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_relname_nsp_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_tblspc_relfilenode_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_tblspc_relfilenode_index\" [label=\"pg_catalog.pg_class_tblspc_\\nrelfilenode_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_tblspc_relfilenode_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=0.75]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnam_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnam_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnam_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_shdepend\" [label=\"pg_catalog.pg_shdepend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_shdepend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_shdepend\" [label=\"pg_catalog.pg_shdepend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_shdepend_reference_index\" [label=\"pg_catalog.pg_shdepend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_shdepend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_shdepend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_shdepend\" [label=\"pg_catalog.pg_shdepend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_shdepend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_depender_index\" [label=\"pg_catalog.pg_depend_\\ndepender_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_depender_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_depender_index\" [label=\"pg_catalog.pg_depend_\\ndepender_index\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_depender_index\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.0]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend_reference_index\" [label=\"pg_catalog.pg_depend_\\nreference_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend_reference_index\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_depend\" [label=\"pg_catalog.pg_depend\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'\tquery_328192 -> \"pg_catalog.pg_depend\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=RowExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class_oid_index\" [label=\"pg_catalog.pg_class_oid_\\nindex\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class_oid_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_class\" [label=\"pg_catalog.pg_class\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_class\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute_relid_attnum_index\" [label=\"pg_catalog.pg_attribute_\\nrelid_attnum_index\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute_relid_attnum_index\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"pg_catalog.pg_attribute\" [label=\"pg_catalog.pg_attribute\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"pg_catalog.pg_attribute\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"pg_catalog.pg_namespace\" [label=\"pg_catalog.pg_namespace\" fillcolor=lightgray shape=box style=filled]',\n'\t\"public.metrics\" [label=\"public.metrics\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"pg_catalog.pg_namespace\" [label=AccessShareLock]',\n'\tquery_328192 -> \"public.metrics\" [label=AccessExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'\t\"public.metrics\" [label=\"public.metrics\" fillcolor=lightgray shape=box style=filled]',\n'\tquery_328192 -> \"public.metrics\" [label=AccessExclusiveLock]',\n'}'],\n['digraph \"lock-graph\" {',\n'\tgraph [mindist=1.7]',\n'\tquery_328192 [label=\"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\" fillcolor=gray style=filled]',\n'}']];\n\n\nupdateFrames();\ninitSlider();\n\n</script>\n"
  },
  {
    "path": "examples/create_table_trace.json",
    "content": "{\"timestamp\": 746704676283500, \"pid\": 328192, \"event\": \"QUERY_BEGIN\", \"query\": \"create table metrics(ts timestamptz NOT NULL, id int NOT NULL, value float);\"}\n{\"timestamp\": 746704676333954, \"pid\": 328192, \"event\": \"TRANSACTION_BEGIN\"}\n{\"timestamp\": 746704676556338, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704676573555, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704676600930, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704676620078, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259, \"lock_local_hold\": 0}\n{\"timestamp\": 746704676637798, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 64243}\n{\"timestamp\": 746704676676605, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_relname_nsp_index\", \"oid\": 2663}\n{\"timestamp\": 746704676700278, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_relname_nsp_index\", \"oid\": 2663}\n{\"timestamp\": 746704676718307, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_relname_nsp_index\", \"oid\": 2663, \"lock_local_hold\": 0}\n{\"timestamp\": 746704676734539, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57934}\n{\"timestamp\": 746704676916162, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_relname_nsp_index\", \"oid\": 2663}\n{\"timestamp\": 746704676935994, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_relname_nsp_index\", \"oid\": 2663}\n{\"timestamp\": 746704676960477, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704676982335, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704677000364, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704677042533, \"pid\": 328192, \"event\": \"LOCK_GRANTED\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_namespace\", \"oid\": 2615}\n{\"timestamp\": 746704677059297, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_namespace\", \"oid\": 2615, \"lock_local_hold\": 0}\n{\"timestamp\": 746704677130926, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_namespace\", \"oid\": 2615, \"lock_local_hold\": 1}\n{\"timestamp\": 746704677224521, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704677241043, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704677265037, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704677282823, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259, \"lock_local_hold\": 0}\n{\"timestamp\": 746704677299007, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57964}\n{\"timestamp\": 746704677335168, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704677350916, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704677373795, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704677391585, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247, \"lock_local_hold\": 0}\n{\"timestamp\": 746704677407426, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56510}\n{\"timestamp\": 746704677430067, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704677453292, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704677470917, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704, \"lock_local_hold\": 0}\n{\"timestamp\": 746704677486958, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56891}\n{\"timestamp\": 746704677654979, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704677673853, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704677697409, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704677718980, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704677783328, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704677818632, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704677842706, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704677860846, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662, \"lock_local_hold\": 0}\n{\"timestamp\": 746704677876838, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 58206}\n{\"timestamp\": 746704677954619, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704677973108, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704678328344, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704678345124, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704678367909, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704678385577, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247, \"lock_local_hold\": 0}\n{\"timestamp\": 746704678401548, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56424}\n{\"timestamp\": 746704678425073, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704678518530, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704678536627, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703, \"lock_local_hold\": 0}\n{\"timestamp\": 746704678552723, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 127650}\n{\"timestamp\": 746704678630504, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704678649158, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704678671189, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704678692375, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704678710119, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704678733846, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704678749716, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704678772331, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704678790185, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247, \"lock_local_hold\": 0}\n{\"timestamp\": 746704678806681, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56965}\n{\"timestamp\": 746704678834178, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704678857069, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704678874840, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703, \"lock_local_hold\": 0}\n{\"timestamp\": 746704678890971, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56793}\n{\"timestamp\": 746704678960527, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704678979302, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704679016766, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704679040320, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704679058271, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703, \"lock_local_hold\": 0}\n{\"timestamp\": 746704679074562, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57796}\n{\"timestamp\": 746704679100293, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704679123512, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704679141251, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704, \"lock_local_hold\": 0}\n{\"timestamp\": 746704679157310, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57017}\n{\"timestamp\": 746704679402113, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704679421747, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704679446017, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704679464279, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704679493790, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704679510271, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704679533670, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704679552280, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608, \"lock_local_hold\": 0}\n{\"timestamp\": 746704679568587, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 58316}\n{\"timestamp\": 746704679594742, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704679618295, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704679636182, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704679652110, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57368}\n{\"timestamp\": 746704679752050, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704679770865, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704679795403, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704679818254, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704679836029, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704679852212, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56809}\n{\"timestamp\": 746704679940788, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704679959228, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704679983803, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680006618, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680024575, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704680040606, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56803}\n{\"timestamp\": 746704680131786, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680150220, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680174890, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680197309, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680214981, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704680231071, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56181}\n{\"timestamp\": 746704680317312, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680336323, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680359602, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704680381513, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704680399519, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704680421854, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704680437476, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704680459915, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704680477484, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608, \"lock_local_hold\": 0}\n{\"timestamp\": 746704680493479, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56003}\n{\"timestamp\": 746704680516046, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680539000, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680556426, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704680572353, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56307}\n{\"timestamp\": 746704680659789, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680678134, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680708322, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704680731675, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704680749555, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673, \"lock_local_hold\": 0}\n{\"timestamp\": 746704680765842, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57520}\n{\"timestamp\": 746704680790981, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680813999, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704680831675, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704680847806, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56825}\n{\"timestamp\": 746704680989448, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704681010372, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704681034018, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704681052346, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704681073720, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704681095005, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704681112656, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704681137265, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681158209, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681175907, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681201239, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681217273, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681240163, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681257962, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247, \"lock_local_hold\": 0}\n{\"timestamp\": 746704681273940, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56667}\n{\"timestamp\": 746704681294500, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704681317288, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704681334828, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704, \"lock_local_hold\": 0}\n{\"timestamp\": 746704681350835, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56335}\n{\"timestamp\": 746704681457495, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704681475984, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704681499135, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681520310, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681537949, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681565426, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681581218, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681603947, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704681621646, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247, \"lock_local_hold\": 0}\n{\"timestamp\": 746704681637638, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56420}\n{\"timestamp\": 746704681674028, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704681697804, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704681715696, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703, \"lock_local_hold\": 0}\n{\"timestamp\": 746704681732028, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 58000}\n{\"timestamp\": 746704681789261, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704681813741, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704681831950, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704, \"lock_local_hold\": 0}\n{\"timestamp\": 746704681848335, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 59074}\n{\"timestamp\": 746704681986220, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704682005166, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_oid_index\", \"oid\": 2703}\n{\"timestamp\": 746704682029300, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704682047617, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type_typname_nsp_index\", \"oid\": 2704}\n{\"timestamp\": 746704682078008, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704682094093, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704682117111, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704682134832, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608, \"lock_local_hold\": 0}\n{\"timestamp\": 746704682151056, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56963}\n{\"timestamp\": 746704682174084, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704682196843, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704682214674, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704682230736, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56652}\n{\"timestamp\": 746704682323576, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704682342453, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704682367129, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704682390600, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704682409007, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704682424956, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57827}\n{\"timestamp\": 746704682826824, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704682845721, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704682870818, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704682894489, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704682912369, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704682929015, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 58197}\n{\"timestamp\": 746704683015112, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683033858, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683057951, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683080989, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683098619, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704683114669, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56718}\n{\"timestamp\": 746704683203101, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683221927, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683245965, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683269041, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683286719, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704683302827, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56862}\n{\"timestamp\": 746704683395707, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683414442, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683438595, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683496427, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683514717, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704683531225, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 92630}\n{\"timestamp\": 746704683616675, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683635066, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683658102, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704683679540, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704683697497, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704683719389, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704683735158, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704683758064, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704683775755, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608, \"lock_local_hold\": 0}\n{\"timestamp\": 746704683791860, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56702}\n{\"timestamp\": 746704683814656, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683837597, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683855313, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704683871469, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56813}\n{\"timestamp\": 746704683953051, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704683971689, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704684000333, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704684023429, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704684040973, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673, \"lock_local_hold\": 0}\n{\"timestamp\": 746704684057015, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56682}\n{\"timestamp\": 746704684080689, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704684103803, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704684121274, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704684137207, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56518}\n{\"timestamp\": 746704684268675, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704684287973, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704684311853, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704684329708, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704684353666, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704684375030, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704684392997, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704684417335, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704684438750, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704684456447, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_type\", \"oid\": 1247}\n{\"timestamp\": 746704684493136, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704684516615, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704684534434, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662, \"lock_local_hold\": 0}\n{\"timestamp\": 746704684550823, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57687}\n{\"timestamp\": 746704684574481, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_relname_nsp_index\", \"oid\": 2663}\n{\"timestamp\": 746704684596862, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_relname_nsp_index\", \"oid\": 2663}\n{\"timestamp\": 746704684614532, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_relname_nsp_index\", \"oid\": 2663, \"lock_local_hold\": 0}\n{\"timestamp\": 746704684630858, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56377}\n{\"timestamp\": 746704684655806, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_tblspc_relfilenode_index\", \"oid\": 3455}\n{\"timestamp\": 746704684678566, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_tblspc_relfilenode_index\", \"oid\": 3455}\n{\"timestamp\": 746704684696029, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_tblspc_relfilenode_index\", \"oid\": 3455, \"lock_local_hold\": 0}\n{\"timestamp\": 746704684712232, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56426}\n{\"timestamp\": 746704684891052, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704684910356, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704684934496, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_relname_nsp_index\", \"oid\": 2663}\n{\"timestamp\": 746704684952910, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_relname_nsp_index\", \"oid\": 2663}\n{\"timestamp\": 746704684976724, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_tblspc_relfilenode_index\", \"oid\": 3455}\n{\"timestamp\": 746704684995182, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class_tblspc_relfilenode_index\", \"oid\": 3455}\n{\"timestamp\": 746704685017751, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704685033785, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704685056178, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704685073827, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249, \"lock_local_hold\": 0}\n{\"timestamp\": 746704685089841, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56056}\n{\"timestamp\": 746704685115419, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnam_index\", \"oid\": 2658}\n{\"timestamp\": 746704685138626, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnam_index\", \"oid\": 2658}\n{\"timestamp\": 746704685156409, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnam_index\", \"oid\": 2658, \"lock_local_hold\": 0}\n{\"timestamp\": 746704685172657, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57238}\n{\"timestamp\": 746704685198120, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnum_index\", \"oid\": 2659}\n{\"timestamp\": 746704685220872, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnum_index\", \"oid\": 2659}\n{\"timestamp\": 746704685238463, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnum_index\", \"oid\": 2659, \"lock_local_hold\": 0}\n{\"timestamp\": 746704685254553, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56433}\n{\"timestamp\": 746704685806308, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704685822934, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704685846226, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704685864348, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608, \"lock_local_hold\": 0}\n{\"timestamp\": 746704685880703, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57769}\n{\"timestamp\": 746704685904218, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704685927560, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704685945300, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704685962114, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57896}\n{\"timestamp\": 746704686056103, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704686074625, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704686098054, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686119932, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686139591, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686161273, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686176771, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686199544, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686217503, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608, \"lock_local_hold\": 0}\n{\"timestamp\": 746704686233510, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56739}\n{\"timestamp\": 746704686256109, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704686278939, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704686296774, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704686312823, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56714}\n{\"timestamp\": 746704686401528, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704686420177, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704686487864, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686510017, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686527884, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686549434, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686565046, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686587786, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686605722, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608, \"lock_local_hold\": 0}\n{\"timestamp\": 746704686621830, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56784}\n{\"timestamp\": 746704686644498, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704686667282, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704686685041, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704686701211, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56713}\n{\"timestamp\": 746704686788616, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704686806947, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704686830285, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686851804, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704686869782, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704687352765, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnam_index\", \"oid\": 2658}\n{\"timestamp\": 746704687371651, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnam_index\", \"oid\": 2658}\n{\"timestamp\": 746704687395545, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnum_index\", \"oid\": 2659}\n{\"timestamp\": 746704687413756, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnum_index\", \"oid\": 2659}\n{\"timestamp\": 746704687435363, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704687456973, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704687474838, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704687496452, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_shdepend\", \"oid\": 1214}\n{\"timestamp\": 746704687512662, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_shdepend\", \"oid\": 1214}\n{\"timestamp\": 746704687544183, \"pid\": 328192, \"event\": \"LOCK_GRANTED\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_shdepend\", \"oid\": 1214}\n{\"timestamp\": 746704687560878, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_shdepend\", \"oid\": 1214, \"lock_local_hold\": 0}\n{\"timestamp\": 746704687578540, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 65878}\n{\"timestamp\": 746704687602868, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_shdepend_reference_index\", \"oid\": 1233}\n{\"timestamp\": 746704687632025, \"pid\": 328192, \"event\": \"LOCK_GRANTED\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_shdepend_reference_index\", \"oid\": 1233}\n{\"timestamp\": 746704687648452, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_shdepend_reference_index\", \"oid\": 1233, \"lock_local_hold\": 0}\n{\"timestamp\": 746704687665995, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 63127}\n{\"timestamp\": 746704687750816, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_shdepend_reference_index\", \"oid\": 1233}\n{\"timestamp\": 746704687773201, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_shdepend_reference_index\", \"oid\": 1233}\n{\"timestamp\": 746704687796972, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_shdepend\", \"oid\": 1214}\n{\"timestamp\": 746704687819103, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_shdepend\", \"oid\": 1214}\n{\"timestamp\": 746704687839622, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_shdepend\", \"oid\": 1214}\n{\"timestamp\": 746704687864038, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704687880413, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704687903277, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704687921449, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608, \"lock_local_hold\": 0}\n{\"timestamp\": 746704687937662, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57249}\n{\"timestamp\": 746704687960911, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704687983767, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688001903, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704688018077, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57166}\n{\"timestamp\": 746704688155154, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688173690, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688200496, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688223459, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688241210, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704688257544, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 57048}\n{\"timestamp\": 746704688345993, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688364398, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688391430, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704688414429, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704688432343, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673, \"lock_local_hold\": 0}\n{\"timestamp\": 746704688448414, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56984}\n{\"timestamp\": 746704688472121, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688494705, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688512407, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674, \"lock_local_hold\": 0}\n{\"timestamp\": 746704688528737, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56616}\n{\"timestamp\": 746704688665251, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704688684168, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_depender_index\", \"oid\": 2673}\n{\"timestamp\": 746704688708032, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688726163, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend_reference_index\", \"oid\": 2674}\n{\"timestamp\": 746704688747719, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704688768970, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704688786812, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_depend\", \"oid\": 2608}\n{\"timestamp\": 746704688812704, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"NoLock\", \"table\": \"public.metrics\", \"oid\": 328345}\n{\"timestamp\": 746704688830423, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704688851604, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704688869376, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"RowExclusiveLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704688912604, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704688928682, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704688952151, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704688970901, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259, \"lock_local_hold\": 0}\n{\"timestamp\": 746704688987015, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 58333}\n{\"timestamp\": 746704689009486, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704689032310, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704689050044, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662, \"lock_local_hold\": 0}\n{\"timestamp\": 746704689066142, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56656}\n{\"timestamp\": 746704689153458, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704689171818, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class_oid_index\", \"oid\": 2662}\n{\"timestamp\": 746704689194876, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704689216684, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704689234574, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_class\", \"oid\": 1259}\n{\"timestamp\": 746704689277572, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704689294145, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704689316974, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704689334868, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249, \"lock_local_hold\": 0}\n{\"timestamp\": 746704689351130, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56985}\n{\"timestamp\": 746704689371726, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnum_index\", \"oid\": 2659}\n{\"timestamp\": 746704689394701, \"pid\": 328192, \"event\": \"LOCK_GRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnum_index\", \"oid\": 2659}\n{\"timestamp\": 746704689412360, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnum_index\", \"oid\": 2659, \"lock_local_hold\": 0}\n{\"timestamp\": 746704689428592, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 56866}\n{\"timestamp\": 746704689658305, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnum_index\", \"oid\": 2659}\n{\"timestamp\": 746704689677092, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute_relid_attnum_index\", \"oid\": 2659}\n{\"timestamp\": 746704689699954, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704689721716, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_FASTPATH\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704689768652, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_attribute\", \"oid\": 1249}\n{\"timestamp\": 746704689815332, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessExclusiveLock\", \"table\": \"public.metrics\", \"oid\": 328345}\n{\"timestamp\": 746704689959625, \"pid\": 328192, \"event\": \"LOCK_GRANTED\", \"lock_type\": \"AccessExclusiveLock\", \"table\": \"public.metrics\", \"oid\": 328345}\n{\"timestamp\": 746704689976218, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessExclusiveLock\", \"table\": \"public.metrics\", \"oid\": 328345, \"lock_local_hold\": 0}\n{\"timestamp\": 746704690002386, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 187054}\n{\"timestamp\": 746704690056281, \"pid\": 328192, \"event\": \"TABLE_OPEN\", \"lock_type\": \"AccessExclusiveLock\", \"table\": \"public.metrics\", \"oid\": 328345}\n{\"timestamp\": 746704690072336, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID\", \"lock_type\": \"AccessExclusiveLock\", \"table\": \"public.metrics\", \"oid\": 328345}\n{\"timestamp\": 746704690093376, \"pid\": 328192, \"event\": \"LOCK_GRANTED_LOCAL\", \"lock_type\": \"AccessExclusiveLock\", \"table\": \"public.metrics\", \"oid\": 328345, \"lock_local_hold\": 1}\n{\"timestamp\": 746704690108444, \"pid\": 328192, \"event\": \"LOCK_RELATION_OID_END\", \"lock_time\": 36108}\n{\"timestamp\": 746704690131202, \"pid\": 328192, \"event\": \"TABLE_CLOSE\", \"lock_type\": \"NoLock\", \"table\": \"public.metrics\", \"oid\": 328345}\n{\"timestamp\": 746704690193553, \"pid\": 328192, \"event\": \"TRANSACTION_COMMIT\"}\n{\"timestamp\": 746704694233743, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_namespace\", \"oid\": 2615}\n{\"timestamp\": 746704694257757, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED_LOCAL\", \"lock_type\": \"AccessExclusiveLock\", \"table\": \"public.metrics\", \"oid\": 328345}\n{\"timestamp\": 746704694313884, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED\", \"lock_type\": \"AccessExclusiveLock\", \"table\": \"public.metrics\", \"oid\": 328345}\n{\"timestamp\": 746704694337362, \"pid\": 328192, \"event\": \"LOCK_UNGRANTED\", \"lock_type\": \"AccessShareLock\", \"table\": \"pg_catalog.pg_namespace\", \"oid\": 2615}\n{\"timestamp\": 746704694803804, \"pid\": 328192, \"event\": \"QUERY_END\"}\n"
  },
  {
    "path": "pylintrc",
    "content": "[MAIN]\n\n# Analyse import fallback blocks. This can be used to support both Python 2 and\n# 3 compatible code, which means that the block might have code that exists\n# only in one or another interpreter, leading to false positives when analysed.\nanalyse-fallback-blocks=no\n\n# Clear in-memory caches upon conclusion of linting. Useful if running pylint\n# in a server-like mode.\nclear-cache-post-run=no\n\n# Load and enable all available extensions. Use --list-extensions to see a list\n# all available extensions.\n#enable-all-extensions=\n\n# In error mode, messages with a category besides ERROR or FATAL are\n# suppressed, and no reports are done by default. Error mode is compatible with\n# disabling specific errors.\n#errors-only=\n\n# Always return a 0 (non-error) status code, even if lint errors are found.\n# This is primarily useful in continuous integration scripts.\n#exit-zero=\n\n# A comma-separated list of package or module names from where C extensions may\n# be loaded. Extensions are loading into the active Python interpreter and may\n# run arbitrary code.\nextension-pkg-allow-list=\n\n# A comma-separated list of package or module names from where C extensions may\n# be loaded. Extensions are loading into the active Python interpreter and may\n# run arbitrary code. (This is an alternative name to extension-pkg-allow-list\n# for backward compatibility.)\nextension-pkg-whitelist=\n\n# Return non-zero exit code if any of these messages/categories are detected,\n# even if score is above --fail-under value. Syntax same as enable. Messages\n# specified are enabled, while categories only check already-enabled messages.\nfail-on=\n\n# Specify a score threshold under which the program will exit with error.\nfail-under=10.0\n\n# Interpret the stdin as a python script, whose filename needs to be passed as\n# the module_or_package argument.\n#from-stdin=\n\n# Files or directories to be skipped. They should be base names, not paths.\nignore=CVS\n\n# Add files or directories matching the regular expressions patterns to the\n# ignore-list. The regex matches against paths and can be in Posix or Windows\n# format. Because '\\\\' represents the directory delimiter on Windows systems,\n# it can't be used as an escape character.\nignore-paths=\n\n# Files or directories matching the regular expression patterns are skipped.\n# The regex matches against base names, not paths. The default value ignores\n# Emacs file locks\nignore-patterns=^\\.#\n\n# List of module names for which member attributes should not be checked\n# (useful for modules/projects where namespaces are manipulated during runtime\n# and thus existing member attributes cannot be deduced by static analysis). It\n# supports qualified module names, as well as Unix pattern matching.\nignored-modules=\n\n# Python code to execute, usually for sys.path manipulation such as\n# pygtk.require().\n#init-hook=\n\n# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the\n# number of processors available to use, and will cap the count on Windows to\n# avoid hangs.\njobs=1\n\n# Control the amount of potential inferred values when inferring a single\n# object. This can help the performance when dealing with large functions or\n# complex, nested conditions.\nlimit-inference-results=100\n\n# List of plugins (as comma separated values of python module names) to load,\n# usually to register additional checkers.\nload-plugins=\n\n# Pickle collected data for later comparisons.\npersistent=yes\n\n# Minimum Python version to use for version dependent checks. Will default to\n# the version used to run pylint.\npy-version=3.9\n\n# Discover python modules and packages in the file system subtree.\nrecursive=no\n\n# When enabled, pylint would attempt to guess common misconfiguration and emit\n# user-friendly hints instead of false-positive error messages.\nsuggestion-mode=yes\n\n# Allow loading of arbitrary C extensions. Extensions are imported into the\n# active Python interpreter and may run arbitrary code.\nunsafe-load-any-extension=no\n\n# In verbose mode, extra non-checker-related info will be displayed.\n#verbose=\n\n\n[BASIC]\n\n# Naming style matching correct argument names.\nargument-naming-style=snake_case\n\n# Regular expression matching correct argument names. Overrides argument-\n# naming-style. If left empty, argument names will be checked with the set\n# naming style.\n#argument-rgx=\n\n# Naming style matching correct attribute names.\nattr-naming-style=snake_case\n\n# Regular expression matching correct attribute names. Overrides attr-naming-\n# style. If left empty, attribute names will be checked with the set naming\n# style.\n#attr-rgx=\n\n# Bad variable names which should always be refused, separated by a comma.\nbad-names=foo,\n          bar,\n          baz,\n          toto,\n          tutu,\n          tata\n\n# Bad variable names regexes, separated by a comma. If names match any regex,\n# they will always be refused\nbad-names-rgxs=\n\n# Naming style matching correct class attribute names.\nclass-attribute-naming-style=any\n\n# Regular expression matching correct class attribute names. Overrides class-\n# attribute-naming-style. If left empty, class attribute names will be checked\n# with the set naming style.\n#class-attribute-rgx=\n\n# Naming style matching correct class constant names.\nclass-const-naming-style=UPPER_CASE\n\n# Regular expression matching correct class constant names. Overrides class-\n# const-naming-style. If left empty, class constant names will be checked with\n# the set naming style.\n#class-const-rgx=\n\n# Naming style matching correct class names.\nclass-naming-style=PascalCase\n\n# Regular expression matching correct class names. Overrides class-naming-\n# style. If left empty, class names will be checked with the set naming style.\n#class-rgx=\n\n# Naming style matching correct constant names.\nconst-naming-style=UPPER_CASE\n\n# Regular expression matching correct constant names. Overrides const-naming-\n# style. If left empty, constant names will be checked with the set naming\n# style.\n#const-rgx=\n\n# Minimum line length for functions/classes that require docstrings, shorter\n# ones are exempt.\ndocstring-min-length=-1\n\n# Naming style matching correct function names.\nfunction-naming-style=snake_case\n\n# Regular expression matching correct function names. Overrides function-\n# naming-style. If left empty, function names will be checked with the set\n# naming style.\n#function-rgx=\n\n# Good variable names which should always be accepted, separated by a comma.\ngood-names=i,\n           j,\n           k,\n           ex,\n           Run,\n           _\n\n# Good variable names regexes, separated by a comma. If names match any regex,\n# they will always be accepted\ngood-names-rgxs=\n\n# Include a hint for the correct naming format with invalid-name.\ninclude-naming-hint=no\n\n# Naming style matching correct inline iteration names.\ninlinevar-naming-style=any\n\n# Regular expression matching correct inline iteration names. Overrides\n# inlinevar-naming-style. If left empty, inline iteration names will be checked\n# with the set naming style.\n#inlinevar-rgx=\n\n# Naming style matching correct method names.\nmethod-naming-style=snake_case\n\n# Regular expression matching correct method names. Overrides method-naming-\n# style. If left empty, method names will be checked with the set naming style.\n#method-rgx=\n\n# Naming style matching correct module names.\nmodule-naming-style=snake_case\n\n# Regular expression matching correct module names. Overrides module-naming-\n# style. If left empty, module names will be checked with the set naming style.\n#module-rgx=\n\n# Colon-delimited sets of names that determine each other's naming style when\n# the name regexes allow several styles.\nname-group=\n\n# Regular expression which should only match function or class names that do\n# not require a docstring.\nno-docstring-rgx=^_\n\n# List of decorators that produce properties, such as abc.abstractproperty. Add\n# to this list to register other decorators that produce valid properties.\n# These decorators are taken in consideration only for invalid-name.\nproperty-classes=abc.abstractproperty\n\n# Regular expression matching correct type variable names. If left empty, type\n# variable names will be checked with the set naming style.\n#typevar-rgx=\n\n# Naming style matching correct variable names.\nvariable-naming-style=snake_case\n\n# Regular expression matching correct variable names. Overrides variable-\n# naming-style. If left empty, variable names will be checked with the set\n# naming style.\n#variable-rgx=\n\n\n[CLASSES]\n\n# Warn about protected attribute access inside special methods\ncheck-protected-access-in-special-methods=no\n\n# List of method names used to declare (i.e. assign) instance attributes.\ndefining-attr-methods=__init__,\n                      __new__,\n                      setUp,\n                      __post_init__\n\n# List of member names, which should be excluded from the protected access\n# warning.\nexclude-protected=_asdict,\n                  _fields,\n                  _replace,\n                  _source,\n                  _make\n\n# List of valid names for the first argument in a class method.\nvalid-classmethod-first-arg=cls\n\n# List of valid names for the first argument in a metaclass class method.\nvalid-metaclass-classmethod-first-arg=cls\n\n\n[DESIGN]\n\n# List of regular expressions of class ancestor names to ignore when counting\n# public methods (see R0903)\nexclude-too-few-public-methods=\n\n# List of qualified class names to ignore when counting class parents (see\n# R0901)\nignored-parents=\n\n# Maximum number of arguments for function / method.\nmax-args=10\n\n# Maximum number of attributes for a class (see R0902).\nmax-attributes=10\n\n# Maximum number of boolean expressions in an if statement (see R0916).\nmax-bool-expr=5\n\n# Maximum number of branch for function / method body.\nmax-branches=12\n\n# Maximum number of locals for function / method body.\nmax-locals=30\n\n# Maximum number of parents for a class (see R0901).\nmax-parents=7\n\n# Maximum number of public methods for a class (see R0904).\nmax-public-methods=25\n\n# Maximum number of return / yield for function / method body.\nmax-returns=20\n\n# Maximum number of statements in function / method body.\nmax-statements=50\n\n# Minimum number of public methods for a class (see R0903).\nmin-public-methods=2\n\nmax-positional-arguments=8\n\n[EXCEPTIONS]\n\n# Exceptions that will emit a warning when caught.\novergeneral-exceptions=builtins.BaseException,builtins.Exception\n\n\n[FORMAT]\n\n# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.\nexpected-line-ending-format=\n\n# Regexp for a line that is allowed to be longer than the limit.\nignore-long-lines=^\\s*(# )?<?https?://\\S+>?$\n\n# Number of spaces of indent required inside a hanging or continued line.\nindent-after-paren=4\n\n# String used as indentation unit. This is usually \"    \" (4 spaces) or \"\\t\" (1\n# tab).\nindent-string='    '\n\n# Maximum number of characters on a single line.\nmax-line-length=100\n\n# Maximum number of lines in a module.\nmax-module-lines=1000\n\n# Allow the body of a class to be on the same line as the declaration if body\n# contains single statement.\nsingle-line-class-stmt=no\n\n# Allow the body of an if to be on the same line as the test if there is no\n# else.\nsingle-line-if-stmt=no\n\n\n[IMPORTS]\n\n# List of modules that can be imported at any level, not just the top level\n# one.\nallow-any-import-level=\n\n# Allow explicit reexports by alias from a package __init__.\nallow-reexport-from-package=no\n\n# Allow wildcard imports from modules that define __all__.\nallow-wildcard-with-all=no\n\n# Deprecated modules which should not be used, separated by a comma.\ndeprecated-modules=\n\n# Output a graph (.gv or any supported image format) of external dependencies\n# to the given file (report RP0402 must not be disabled).\next-import-graph=\n\n# Output a graph (.gv or any supported image format) of all (i.e. internal and\n# external) dependencies to the given file (report RP0402 must not be\n# disabled).\nimport-graph=\n\n# Output a graph (.gv or any supported image format) of internal dependencies\n# to the given file (report RP0402 must not be disabled).\nint-import-graph=\n\n# Force import order to recognize a module as part of the standard\n# compatibility libraries.\nknown-standard-library=\n\n# Force import order to recognize a module as part of a third party library.\nknown-third-party=enchant\n\n# Couples of modules and preferred modules, separated by a comma.\npreferred-modules=\n\n\n[LOGGING]\n\n# The type of string formatting that logging methods do. `old` means using %\n# formatting, `new` is for `{}` formatting.\nlogging-format-style=old\n\n# Logging modules to check that the string format arguments are in logging\n# function parameter format.\nlogging-modules=logging\n\n\n[MESSAGES CONTROL]\n\n# Only show warnings with the listed confidence levels. Leave empty to show\n# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE,\n# UNDEFINED.\nconfidence=HIGH,\n           CONTROL_FLOW,\n           INFERENCE,\n           INFERENCE_FAILURE,\n           UNDEFINED\n\n# Disable the message, report, category or checker with the given id(s). You\n# can either give multiple identifiers separated by comma (,) or put this\n# option multiple times (only on the command line, not in the configuration\n# file where it should appear only once). You can also use \"--disable=all\" to\n# disable everything first and then re-enable specific checks. For example, if\n# you want to run only the similarities checker, you can use \"--disable=all\n# --enable=similarities\". If you want to run only the classes checker, but have\n# no Warning level messages displayed, use \"--disable=all --enable=classes\n# --disable=W\".\ndisable=raw-checker-failed,\n        bad-inline-option,\n        locally-disabled,\n        file-ignored,\n        suppressed-message,\n        useless-suppression,\n        deprecated-pragma,\n        use-symbolic-message-instead,\n        missing-module-docstring,\n        missing-class-docstring,\n        missing-function-docstring\n\n# Enable the message, report, category or checker with the given id(s). You can\n# either give multiple identifier separated by comma (,) or put this option\n# multiple time (only on the command line, not in the configuration file where\n# it should appear only once). See also the \"--disable\" option for examples.\nenable=c-extension-no-member\n\n\n[METHOD_ARGS]\n\n# List of qualified names (i.e., library.method) which require a timeout\n# parameter e.g. 'requests.api.get,requests.api.post'\ntimeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request\n\n\n[MISCELLANEOUS]\n\n# List of note tags to take in consideration, separated by a comma.\nnotes=FIXME,\n      XXX,\n      TODO\n\n# Regular expression of note tags to take in consideration.\nnotes-rgx=\n\n\n[REFACTORING]\n\n# Maximum number of nested blocks for function / method body\nmax-nested-blocks=5\n\n# Complete name of functions that never returns. When checking for\n# inconsistent-return-statements if a never returning function is called then\n# it will be considered as an explicit return statement and no message will be\n# printed.\nnever-returning-functions=sys.exit,argparse.parse_error\n\n\n[REPORTS]\n\n# Python expression which should return a score less than or equal to 10. You\n# have access to the variables 'fatal', 'error', 'warning', 'refactor',\n# 'convention', and 'info' which contain the number of messages in each\n# category, as well as 'statement' which is the total number of statements\n# analyzed. This score is used by the global evaluation report (RP0004).\nevaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10))\n\n# Template used to display messages. This is a python new-style format string\n# used to format the message information. See doc for all details.\nmsg-template=\n\n# Set the output format. Available formats are text, parseable, colorized, json\n# and msvs (visual studio). You can also give a reporter class, e.g.\n# mypackage.mymodule.MyReporterClass.\n#output-format=\n\n# Tells whether to display a full report or only the messages.\nreports=no\n\n# Activate the evaluation score.\nscore=yes\n\n\n[SIMILARITIES]\n\n# Comments are removed from the similarity computation\nignore-comments=yes\n\n# Docstrings are removed from the similarity computation\nignore-docstrings=yes\n\n# Imports are removed from the similarity computation\nignore-imports=no\n\n# Signatures are removed from the similarity computation\nignore-signatures=no\n\n# Minimum lines number of a similarity.\nmin-similarity-lines=4\n\n\n[SPELLING]\n\n# Limits count of emitted suggestions for spelling mistakes.\nmax-spelling-suggestions=4\n\n# Spelling dictionary name. Available dictionaries: none. To make it work,\n# install the 'python-enchant' package.\nspelling-dict=\n\n# List of comma separated words that should be considered directives if they\n# appear at the beginning of a comment and should not be checked.\nspelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:\n\n# List of comma separated words that should not be checked.\nspelling-ignore-words=\n\n# A path to a file that contains the private dictionary; one word per line.\nspelling-private-dict-file=\n\n# Tells whether to store unknown words to the private dictionary (see the\n# --spelling-private-dict-file option) instead of raising a message.\nspelling-store-unknown-words=no\n\n\n[STRING]\n\n# This flag controls whether inconsistent-quotes generates a warning when the\n# character used as a quote delimiter is used inconsistently within a module.\ncheck-quote-consistency=no\n\n# This flag controls whether the implicit-str-concat should generate a warning\n# on implicit string concatenation in sequences defined over several lines.\ncheck-str-concat-over-line-jumps=no\n\n\n[TYPECHECK]\n\n# List of decorators that produce context managers, such as\n# contextlib.contextmanager. Add to this list to register other decorators that\n# produce valid context managers.\ncontextmanager-decorators=contextlib.contextmanager\n\n# List of members which are set dynamically and missed by pylint inference\n# system, and so shouldn't trigger E1101 when accessed. Python regular\n# expressions are accepted.\ngenerated-members=\n\n# Tells whether to warn about missing members when the owner of the attribute\n# is inferred to be None.\nignore-none=yes\n\n# This flag controls whether pylint should warn about no-member and similar\n# checks whenever an opaque object is returned when inferring. The inference\n# can return multiple potential results while evaluating a Python object, but\n# some branches might not be evaluated, which results in partial inference. In\n# that case, it might be useful to still emit no-member and other checks for\n# the rest of the inferred objects.\nignore-on-opaque-inference=yes\n\n# List of symbolic message names to ignore for Mixin members.\nignored-checks-for-mixins=no-member,\n                          not-async-context-manager,\n                          not-context-manager,\n                          attribute-defined-outside-init\n\n# List of class names for which member attributes should not be checked (useful\n# for classes with dynamically set attributes). This supports the use of\n# qualified names.\nignored-classes=optparse.Values,thread._local,_thread._local\n\n# Show a hint with possible names when a member name was not found. The aspect\n# of finding the hint is based on edit distance.\nmissing-member-hint=yes\n\n# The minimum edit distance a name should have in order to be considered a\n# similar match for a missing member name.\nmissing-member-hint-distance=1\n\n# The total number of similar names that should be taken in consideration when\n# showing a hint for a missing member.\nmissing-member-max-choices=1\n\n# Regex pattern to define which classes are considered mixins.\nmixin-class-rgx=.*[Mm]ixin\n\n# List of decorators that change the signature of a decorated function.\nsignature-mutators=\n\n\n[VARIABLES]\n\n# List of additional names supposed to be defined in builtins. Remember that\n# you should avoid defining new builtins when possible.\nadditional-builtins=\n\n# Tells whether unused global variables should be treated as a violation.\nallow-global-unused-variables=yes\n\n# List of names allowed to shadow builtins\nallowed-redefined-builtins=\n\n# List of strings which can identify a callback function by name. A callback\n# name must start or end with one of those strings.\ncallbacks=cb_,\n          _cb\n\n# A regular expression matching the name of dummy variables (i.e. expected to\n# not be used).\ndummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_\n\n# Argument names that match this expression will be ignored.\nignored-argument-names=_.*|^ignored_|^unused_\n\n# Tells whether we should check for unused import in __init__ files.\ninit-import=no\n\n# List of qualified module names which can have objects that can redefine\n# builtins.\nredefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[build-system]\nrequires = [\"setuptools>=59\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"pg_lock_tracer\"\ndescription = \"An eBPF based lock tracer for PostgreSQL\"\nreadme = { file = \"README.md\", content-type = \"text/markdown\" }\nrequires-python = \">=3.10\"\nlicense = \"Apache-2.0\"\nlicense-files = [\n    \"LICENSE\",\n]\nauthors = [\n\t{ name = \"Jan Nidzwetzki\", email = \"jnidzwetzki@gmx.de\" },\n]\nkeywords = [\"postgresql\", \"postgres\", \"ebpf\", \"locktracer\"]\nclassifiers = [\n\t\"Development Status :: 4 - Beta\",\n\t\"Intended Audience :: Developers\",\n\t\"Operating System :: POSIX :: Linux\",\n\t\"Programming Language :: Python\",\n\t\"Topic :: Software Development :: Debuggers\"\n]\ndependencies = [\n\t\"graphviz\",\n\t\"igraph\",\n\t\"prettytable\",\n\t\"psycopg2\",\n]\ndynamic = [\"version\"]\n\n[project.urls]\nHomepage = \"https://github.com/jnidzwetzki/pg-lock-tracer\"\n\"Bug Tracker\" = \"https://github.com/jnidzwetzki/pg-lock-tracer/issues\"\n\n[project.scripts]\npg_lock_tracer = \"pg_lock_tracer.pg_lock_tracer:main\"\npg_lw_lock_tracer = \"pg_lock_tracer.pg_lw_lock_tracer:main\"\npg_row_lock_tracer = \"pg_lock_tracer.pg_row_lock_tracer:main\"\npg_spinlock_delay_tracer = \"pg_lock_tracer.pg_spinlock_delay_tracer:main\"\nanimate_lock_graph = \"pg_lock_tracer.animate_lock_graph:main\"\n\n[tool.setuptools]\npackage-dir = { \"\" = \"src\" }\n\n[tool.setuptools.packages.find]\nwhere = [\"src\"]\n\n[tool.setuptools.package-data]\n\"pg_lock_tracer.bpf\" = [\"*.c\"]\n\n[tool.setuptools.dynamic]\nversion = { attr = \"pg_lock_tracer.__version__\" }\n\n[tool.pytest.ini_options]\ntestpaths = [\"tests/\"]\naddopts = [\n\t\"--verbose\",\n\t\"--ignore-glob=**/_*.py\",\n]\n\n"
  },
  {
    "path": "requirements_dev.txt",
    "content": "astroid==4.0.3\nattrs==26.1.0\nblack==26.3.1\nclick==8.3.3\ndill==0.4.1\nexceptiongroup==1.3.1\ngraphviz==0.21\nigraph==1.0.0\niniconfig==2.3.0\nisort==8.0.1\nlazy-object-proxy==1.12.0\nmccabe==0.7.0\nmypy-extensions==1.1.0\npackaging==26.2\npathspec==1.1.1\nplatformdirs==4.9.6\npluggy==1.6.0\nprettytable==3.17.0\npsycopg2==2.9.12\npylint==4.0.5\npytest==9.0.3\ntexttable==1.7.0\ntomli==2.4.1\ntyping-extensions==4.15.0\nwcwidth==0.7.0\nwrapt==2.1.2\n"
  },
  {
    "path": "src/pg_lock_tracer/__init__.py",
    "content": "__version__ = \"0.7.1\"\n"
  },
  {
    "path": "src/pg_lock_tracer/animate_lock_graph.py",
    "content": "#!/usr/bin/env python3\n#\n# Generate an animated version of the locks\n# of a query. Input data is the JSON output of\n# pg_lock_tracker.\n#\n# Current limitations:\n# * Only lock traces of one query are supported.\n##########################\n\nimport os\nimport json\nimport argparse\n\nimport igraph\nimport graphviz\n\nfrom pg_lock_tracer import __version__\nfrom pg_lock_tracer.helper import PostgreSQLLockHelper\n\n# See https://github.com/magjac/d3-graphviz/blob/master/examples/basic-unpkg-worker.html\nHTML_TEMPLATE = \"\"\"\n<!DOCTYPE html>\n<meta charset=\"utf-8\">\n<body>\n<script src=\"https://d3js.org/d3.v7.js\"></script>\n<script src=\"https://unpkg.com/@hpcc-js/wasm@2/dist/graphviz.umd.js\"></script>\n<script src=\"https://unpkg.com/d3-graphviz@5/build/d3-graphviz.js\"></script>\n\n<style>\n.frame_div {\n   display: inline-block;\n}\n\n#frame_control {\n   background-color: lightgray;\n   height: 24px;\n   margin-bottom: 5px;\n   padding-left: 5px;\n}\n\n#pause_control {\n   padding-left: 20px;\n}\n\ninput, output {\n  vertical-align: middle;\n}\n</style>\n<div id=\"frame_control\">\n  Frame <input type=\"range\" id=\"active_frame_slider\" min=\"0\" max=\"100\" value=\"0\" oninput=\"updateSlider(this.value);\" onchange=\"render();\">\n  <div id=\"frames\" class=\"frame_div\">\n     (<div id=\"cur_frame\" class=\"frame_div\"></div> of <div id=\"total_frame\" class=\"frame_div\"></div>)\n  </div>\n  <div id=\"pause_control\" class=\"frame_div\">\n    <input type=\"checkbox\" id=\"render_active\" name=\"render_active\" value=\"active\" checked onclick=\"render();\">\n     <label for=\"render_active\" style=\"vertical-align: bottom;\">&#9658; Play</label>\n    </input>\n  </div>\n</div>\n\n<div id=\"graph\" style=\"text-align: center;\"></div>\n\n<script>\nvar dotIndex = 0;\n\nvar graphviz = d3.select(\"#graph\").graphviz()\n    .attributer(attributer)\n    .transition(function () {\n        return d3.transition(\"main\")\n            .ease(d3.easeLinear)\n            .delay(500)\n            .duration(1500);\n    })\n    .logEvents(true)\n    .engine('circo')\n    .on(\"initEnd\", render);\n\nfunction render() {\n    var dotLines = dots[dotIndex];\n    var dot = dotLines.join('');\n    graphviz\n        .renderDot(dot)\n        .on(\"end\", function () {\n            if (! document.getElementById('render_active').checked) {\n                return;\n            }\n            dotIndex = (dotIndex + 1) % dots.length;\n            updateFrames();\n            document.getElementById(\"active_frame_slider\").value = dotIndex;\n            render();\n        })\n        .zoom(true);\n}\n\nfunction updateFrames() {\n    document.getElementById(\"cur_frame\").innerHTML = dotIndex;\n    document.getElementById(\"total_frame\").innerHTML = dots.length;\n}\n\nfunction updateSlider(newValue) {\n    dotIndex = Number(newValue);\n    updateFrames();\n}\n\nfunction initSlider() {\n    document.getElementById(\"active_frame_slider\").value = dotIndex;\n    document.getElementById(\"active_frame_slider\").max = dots.length;\n}\n\nfunction attributer(datum, index, nodes) {\n    marginWidth = 20; // to avoid scrollbars\n    marginHeight = 40;\n    var selection = d3.select(this);\n    if (datum.tag == \"svg\") {\n        var width = window.innerWidth;\n        var height = window.innerHeight;\n        datum.attributes.width = width - marginWidth;\n        datum.attributes.height = height - marginHeight;\n    }\n}\n\n\n%%DOT_TEMPLATE%%\n\nupdateFrames();\ninitSlider();\n\n</script>\n\"\"\"\n\nEXAMPLES = \"\"\"\n\nusage examples:\n\n# Read events from 'test_trace.json' and generate 'test.html'\nanimate_lock_graph.py -i test_trace.json -o test.html\n\"\"\"\n\nparser = argparse.ArgumentParser(\n    description=\"\",\n    formatter_class=argparse.RawDescriptionHelpFormatter,\n    epilog=EXAMPLES,\n)\nparser.add_argument(\n    \"-V\",\n    \"--version\",\n    action=\"version\",\n    version=f\"{parser.prog} ({__version__})\",\n)\nparser.add_argument(\"-v\", \"--verbose\", action=\"store_true\", help=\"be verbose\")\nparser.add_argument(\n    \"-o\",\n    \"--output\",\n    type=str,\n    dest=\"output_file\",\n    default=None,\n    help=\"write the trace into output file\",\n    required=True,\n)\nparser.add_argument(\n    \"-i\",\n    \"--input\",\n    type=str,\n    dest=\"input_file\",\n    default=None,\n    help=\"the input file with the events\",\n    required=True,\n)\nparser.add_argument(\n    \"-f\",\n    \"--force\",\n    action=\"store_true\",\n    help=\"overwrite the output file if it already exists\",\n)\n\n\nclass DOTModel:\n    def __init__(self, input_file, verbose) -> None:\n        self.input_file = input_file\n        self.verbose = verbose\n        self.dot_graphs = []\n        self.graph = igraph.Graph(directed=True)\n        self.calculate_graphs()\n\n    def calculate_graphs(self):\n        \"\"\"\n        Calculate the dot graphs for each line of the input\n        \"\"\"\n        with open(self.input_file, \"r\", encoding=\"utf-8\") as input_file_handle:\n            for line in input_file_handle:\n                json_data = json.loads(line)\n                self.handle_json(json_data)\n\n    def handle_json(self, event):\n        \"\"\"\n        Handle the JSON encoded graph event\n        \"\"\"\n        vertex_name_query = f\"query_{event['pid']}\"\n\n        if event[\"event\"] == \"QUERY_BEGIN\":\n            self.graph.add_vertex(vertex_name_query, type=\"query\", label=event[\"query\"])\n            self.generate_graph()\n            return\n\n        if event[\"event\"] == \"LOCK_GRANTED_LOCAL\":\n            if self.verbose:\n                print(f\"Processing {event}\")\n\n            tablename = StringHelper.get_tablename(event)\n            lock_type = event[\"lock_type\"]\n\n            if not self.graph.vs.select(label_eq=tablename):\n                self.graph.add_vertex(tablename, label=tablename)\n\n            # Get numeric value of lock\n            lock_numeric_value = PostgreSQLLockHelper.lock_type_to_int(lock_type)\n\n            # Get existing edge to this table\n            edge_id = self.graph.get_eid(vertex_name_query, tablename, error=False)\n\n            # If not exist, create\n            if edge_id == -1:\n                lock_value = PostgreSQLLockHelper.encode_locks_into_value(\n                    [lock_numeric_value]\n                )\n                self.graph.add_edge(vertex_name_query, tablename, lock_value=lock_value)\n                self.generate_graph()\n                return\n\n            # Else, modify edge and add lock\n            edge = self.graph.es[edge_id]\n            decoded_lock_value = PostgreSQLLockHelper.decode_locks_from_value(\n                edge[\"lock_value\"]\n            )\n            decoded_lock_value.append(lock_numeric_value)\n            edge[\"lock_value\"] = PostgreSQLLockHelper.encode_locks_into_value(\n                decoded_lock_value\n            )\n\n            return\n\n        if event[\"event\"] == \"LOCK_UNGRANTED_LOCAL\":\n            if self.verbose:\n                print(f\"Processing {event}\")\n\n            tablename = StringHelper.get_tablename(event)\n            lock_type = event[\"lock_type\"]\n            lock_numeric_value = PostgreSQLLockHelper.lock_type_to_int(lock_type)\n\n            edge_id = self.graph.get_eid(vertex_name_query, tablename)\n            edge = self.graph.es[edge_id]\n\n            decoded_lock_value = PostgreSQLLockHelper.decode_locks_from_value(\n                edge[\"lock_value\"]\n            )\n\n            if lock_numeric_value in decoded_lock_value:\n                decoded_lock_value.remove(lock_numeric_value)\n            else:\n                print(\n                    f\"Lock {lock_numeric_value} for table {tablename} removed but not requested\"\n                )\n\n            edge[\"lock_value\"] = PostgreSQLLockHelper.encode_locks_into_value(\n                decoded_lock_value\n            )\n\n            # Delete the edge if not locks hold\n            if len(decoded_lock_value) == 0:\n                self.graph.delete_edges(edge)\n\n            # Is the vertex unconnected (degree == 0) after we deleted the edge?\n            vertex = self.graph.vs.select(label_eq=tablename)\n            if self.graph.degree(vertex)[0] == 0:\n                # self.graph.delete_vertices(tablename)\n                self.graph.delete_vertices(vertex)\n\n            self.generate_graph()\n            return\n\n    def generate_graph(self):\n        \"\"\"\n        Generate a DOT graph based on the igraph\n        \"\"\"\n        vertices = self.graph.vs\n        edges = self.graph.es\n\n        # Reduce space if more nodes are present\n        if len(vertices) > 15:\n            mindist = \"0.2\"\n        elif len(vertices) > 10:\n            mindist = \"0.4\"\n        elif len(vertices) > 6:\n            mindist = \"0.75\"\n        elif len(vertices) > 4:\n            mindist = \"1.0\"\n        else:\n            mindist = \"1.7\"\n\n        dot = graphviz.Digraph(\"lock-graph\", graph_attr={\"mindist\": mindist})\n\n        for vertex in vertices:\n            if vertex[\"type\"] == \"query\":\n                dot.node(\n                    vertex[\"name\"], vertex[\"label\"], fillcolor=\"gray\", style=\"filled\"\n                )\n            else:\n                display_name = vertex[\"label\"]\n                display_name = StringHelper.split_string(display_name, 20)\n                dot.node(\n                    vertex[\"name\"],\n                    display_name,\n                    shape=\"box\",\n                    fillcolor=\"lightgray\",\n                    style=\"filled\",\n                )\n\n        for edge in edges:\n            # Decode graph lock value into list of lock values\n            decoded_lock_value = PostgreSQLLockHelper.decode_locks_from_value(\n                edge[\"lock_value\"]\n            )\n\n            # Convert numeric lock values into a string values and join them into a single string\n            label = \",\".join(\n                map(PostgreSQLLockHelper.lock_type_to_str, decoded_lock_value)\n            )\n\n            # Add edge to dot graph\n            dot.edge(\n                vertices[edge.source][\"name\"],\n                vertices[edge.target][\"name\"],\n                label=label,\n            )\n\n        # Convert Dot graph into string.\n        # Every line needs to be quoted and line breaks need a \",\"\"\n        #\n        # For example:\n        #\n        # ['digraph \"lock-graph\" {',\n        # '       query_171379 [label=\"select count(*) from sensor_data ;\"]',\n        # '       \"public.sensor_data\" [label=\"public.sensor_data\"]',\n        # '       query_171379 -> \"public.sensor_data\"',\n        # '}'],\n        lines = dot.source.split(\"\\n\")\n        lines = [f\"'{line}'\" for line in lines if line]\n        lines = \",\\n\".join(lines)\n\n        # Add dot string to list of graphs\n        self.dot_graphs.append(f\"[{lines}]\")\n\n    def get_html(self):\n        \"\"\"\n        Convert all dot graphs into a single string\n        \"\"\"\n        result = \"var dots = [\\n\"\n        graphs = \",\\n\".join(self.dot_graphs)\n        result += graphs\n        result += \"];\\n\"\n        return result\n\n\n# pylint: disable=too-few-public-methods\nclass StringHelper:\n    @staticmethod\n    def split_string(mystring, max_length):\n        \"\"\"\n        Add linebreaks to the string after max_length chars at\n        the next dot or underscore.\n        \"\"\"\n\n        result = \"\"\n        chars_without_break = 0\n        for element in mystring:\n            result += element\n            chars_without_break += 1\n\n            if chars_without_break > max_length and element in (\".\", \"_\"):\n                chars_without_break = 0\n                result += \"\\\\n\"\n\n        return result\n\n    @staticmethod\n    def get_tablename(event):\n        \"\"\"\n        Get the tablename or the Oid of the event.\n        \"\"\"\n        if \"table\" in event:\n            return event[\"table\"]\n\n        return f\"Oid {event['oid']}\"\n\n\ndef main():\n    \"\"\"\n    Entry point for the animate_lock_graph script\n    \"\"\"\n    args = parser.parse_args()\n\n    if not os.path.exists(args.input_file):\n        raise ValueError(f\"Input file does not exist {args.input_file}\")\n\n    if os.path.exists(args.output_file) and not args.force:\n        raise ValueError(f\"Output file already exists {args.output_file}\")\n\n    # Create a new dot model, process the events in the input file\n    # and generate the HTML output\n    dot_model_instance = DOTModel(args.input_file, args.verbose)\n\n    with open(args.output_file, \"w\", encoding=\"utf-8\") as output:\n        dots = dot_model_instance.get_html()\n        output_html = HTML_TEMPLATE.replace(\"%%DOT_TEMPLATE%%\", dots)\n        output.write(output_html)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/pg_lock_tracer/bpf/.clang-format",
    "content": "---\nLanguage:        Cpp\n# BasedOnStyle:  Google\nAccessModifierOffset: -1\nAlignAfterOpenBracket: Align\nAlignArrayOfStructures: None\nAlignConsecutiveMacros: None\nAlignConsecutiveAssignments: None\nAlignConsecutiveBitFields: None\nAlignConsecutiveDeclarations: None\nAlignEscapedNewlines: Left\nAlignOperands:   Align\nAlignTrailingComments: true\nAllowAllArgumentsOnNextLine: true\nAllowAllParametersOfDeclarationOnNextLine: true\nAllowShortEnumsOnASingleLine: true\nAllowShortBlocksOnASingleLine: Never\nAllowShortCaseLabelsOnASingleLine: false\nAllowShortFunctionsOnASingleLine: All\nAllowShortLambdasOnASingleLine: All\nAllowShortIfStatementsOnASingleLine: WithoutElse\nAllowShortLoopsOnASingleLine: true\nAlwaysBreakAfterDefinitionReturnType: None\nAlwaysBreakAfterReturnType: None\nAlwaysBreakBeforeMultilineStrings: true\nAlwaysBreakTemplateDeclarations: Yes\nAttributeMacros:\n  - __capability\nBinPackArguments: true\nBinPackParameters: true\nBraceWrapping:\n  AfterCaseLabel:  false\n  AfterClass:      false\n  AfterControlStatement: Never\n  AfterEnum:       false\n  AfterFunction:   false\n  AfterNamespace:  false\n  AfterObjCDeclaration: false\n  AfterStruct:     false\n  AfterUnion:      false\n  AfterExternBlock: false\n  BeforeCatch:     false\n  BeforeElse:      false\n  BeforeLambdaBody: false\n  BeforeWhile:     false\n  IndentBraces:    false\n  SplitEmptyFunction: true\n  SplitEmptyRecord: true\n  SplitEmptyNamespace: true\nBreakBeforeBinaryOperators: None\nBreakBeforeConceptDeclarations: true\nBreakBeforeBraces: Attach\nBreakBeforeInheritanceComma: false\nBreakInheritanceList: BeforeColon\nBreakBeforeTernaryOperators: true\nBreakConstructorInitializersBeforeComma: false\nBreakConstructorInitializers: BeforeColon\nBreakAfterJavaFieldAnnotations: false\nBreakStringLiterals: true\nColumnLimit:     80\nCommentPragmas:  '^ IWYU pragma:'\nQualifierAlignment: Leave\nCompactNamespaces: false\nConstructorInitializerIndentWidth: 4\nContinuationIndentWidth: 4\nCpp11BracedListStyle: true\nDeriveLineEnding: true\nDerivePointerAlignment: true\nDisableFormat:   false\nEmptyLineAfterAccessModifier: Never\nEmptyLineBeforeAccessModifier: LogicalBlock\nExperimentalAutoDetectBinPacking: false\nPackConstructorInitializers: NextLine\nBasedOnStyle:    ''\nConstructorInitializerAllOnOneLineOrOnePerLine: false\nAllowAllConstructorInitializersOnNextLine: true\nFixNamespaceComments: true\nForEachMacros:\n  - foreach\n  - Q_FOREACH\n  - BOOST_FOREACH\nIfMacros:\n  - KJ_IF_MAYBE\nIncludeBlocks:   Regroup\nIncludeCategories:\n  - Regex:           '^<ext/.*\\.h>'\n    Priority:        2\n    SortPriority:    0\n    CaseSensitive:   false\n  - Regex:           '^<.*\\.h>'\n    Priority:        1\n    SortPriority:    0\n    CaseSensitive:   false\n  - Regex:           '^<.*'\n    Priority:        2\n    SortPriority:    0\n    CaseSensitive:   false\n  - Regex:           '.*'\n    Priority:        3\n    SortPriority:    0\n    CaseSensitive:   false\nIncludeIsMainRegex: '([-_](test|unittest))?$'\nIncludeIsMainSourceRegex: ''\nIndentAccessModifiers: false\nIndentCaseLabels: true\nIndentCaseBlocks: false\nIndentGotoLabels: true\nIndentPPDirectives: None\nIndentExternBlock: AfterExternBlock\nIndentRequires:  false\nIndentWidth:     2\nIndentWrappedFunctionNames: false\nInsertTrailingCommas: None\nJavaScriptQuotes: Leave\nJavaScriptWrapImports: true\nKeepEmptyLinesAtTheStartOfBlocks: false\nLambdaBodyIndentation: Signature\nMacroBlockBegin: ''\nMacroBlockEnd:   ''\nMaxEmptyLinesToKeep: 1\nNamespaceIndentation: None\nObjCBinPackProtocolList: Never\nObjCBlockIndentWidth: 2\nObjCBreakBeforeNestedBlockParam: true\nObjCSpaceAfterProperty: false\nObjCSpaceBeforeProtocolList: true\nPenaltyBreakAssignment: 2\nPenaltyBreakBeforeFirstCallParameter: 1\nPenaltyBreakComment: 300\nPenaltyBreakFirstLessLess: 120\nPenaltyBreakOpenParenthesis: 0\nPenaltyBreakString: 1000\nPenaltyBreakTemplateDeclaration: 10\nPenaltyExcessCharacter: 1000000\nPenaltyReturnTypeOnItsOwnLine: 200\nPenaltyIndentedWhitespace: 0\nPointerAlignment: Left\nPPIndentWidth:   -1\nRawStringFormats:\n  - Language:        Cpp\n    Delimiters:\n      - cc\n      - CC\n      - cpp\n      - Cpp\n      - CPP\n      - 'c++'\n      - 'C++'\n    CanonicalDelimiter: ''\n    BasedOnStyle:    google\n  - Language:        TextProto\n    Delimiters:\n      - pb\n      - PB\n      - proto\n      - PROTO\n    EnclosingFunctions:\n      - EqualsProto\n      - EquivToProto\n      - PARSE_PARTIAL_TEXT_PROTO\n      - PARSE_TEST_PROTO\n      - PARSE_TEXT_PROTO\n      - ParseTextOrDie\n      - ParseTextProtoOrDie\n      - ParseTestProto\n      - ParsePartialTestProto\n    CanonicalDelimiter: pb\n    BasedOnStyle:    google\nReferenceAlignment: Pointer\nReflowComments:  true\nRemoveBracesLLVM: false\nSeparateDefinitionBlocks: Leave\nShortNamespaceLines: 1\nSortIncludes:    CaseSensitive\nSortJavaStaticImport: Before\nSortUsingDeclarations: true\nSpaceAfterCStyleCast: false\nSpaceAfterLogicalNot: false\nSpaceAfterTemplateKeyword: true\nSpaceBeforeAssignmentOperators: true\nSpaceBeforeCaseColon: false\nSpaceBeforeCpp11BracedList: false\nSpaceBeforeCtorInitializerColon: true\nSpaceBeforeInheritanceColon: true\nSpaceBeforeParens: ControlStatements\nSpaceBeforeParensOptions:\n  AfterControlStatements: true\n  AfterForeachMacros: true\n  AfterFunctionDefinitionName: false\n  AfterFunctionDeclarationName: false\n  AfterIfMacros:   true\n  AfterOverloadedOperator: false\n  BeforeNonEmptyParentheses: false\nSpaceAroundPointerQualifiers: Default\nSpaceBeforeRangeBasedForLoopColon: true\nSpaceInEmptyBlock: false\nSpaceInEmptyParentheses: false\nSpacesBeforeTrailingComments: 2\nSpacesInAngles:  Never\nSpacesInConditionalStatement: false\nSpacesInContainerLiterals: true\nSpacesInCStyleCastParentheses: false\nSpacesInLineCommentPrefix:\n  Minimum:         1\n  Maximum:         -1\nSpacesInParentheses: false\nSpacesInSquareBrackets: false\nSpaceBeforeSquareBrackets: false\nBitFieldColonSpacing: Both\nStandard:        Auto\nStatementAttributeLikeMacros:\n  - Q_EMIT\nStatementMacros:\n  - Q_UNUSED\n  - QT_REQUIRE_VERSION\nTabWidth:        8\nUseCRLF:         false\nUseTab:          Never\nWhitespaceSensitiveMacros:\n  - STRINGIZE\n  - PP_STRINGIZE\n  - BOOST_PP_STRINGIZE\n  - NS_SWIFT_NAME\n  - CF_SWIFT_NAME\n...\n\n"
  },
  {
    "path": "src/pg_lock_tracer/bpf/__init__.py",
    "content": ""
  },
  {
    "path": "src/pg_lock_tracer/bpf/pg_lock_tracer.c",
    "content": "#include <uapi/linux/ptrace.h>\n\n/*\n * Placeholder for EVENT_* and ERROR_* defines\n *\n * #define EVENT_.... n\n *\n * Will by automatically generated from python Events ENUM\n */\n__DEFINES__\n\ntypedef struct PostgreSQLEvent {\n  u32 pid;\n  u64 timestamp;\n  u32 event_type;\n\n  u32 object;           // typedef unsigned int Oid;\n  int mode;             // typedef int LOCKMODE;\n  u32 requested;        // Requested locks\n  s64 lock_local_hold;  // Requested local locks\n\n  char payload_str1[127];  // Generic payload string data 1 (e.g., a query / a\n                           // schema)\n  char payload_str2[127];  // Generic payload string data 2 (e.g., a table)\n\n  int stackid;  // The id of the stack\n} PostgreSQLEvent;\n\nBPF_PERF_OUTPUT(lockevents);\n\n#if defined(STACKTRACE_DEADLOCK) || defined(STACKTRACE_LOCK) || \\\n    defined(STACKTRACE_UNLOCK)\nBPF_STACK_TRACE(stacks, 4096);\n#endif\n\nstatic void fill_basic_data(PostgreSQLEvent *event) {\n  event->pid = bpf_get_current_pid_tgid();\n  event->timestamp = bpf_ktime_get_ns();\n}\n\n/*\n * ====================================\n * Table handling\n * ====================================\n */\n\nstatic void handle_table_event(PostgreSQLEvent *event, struct pt_regs *ctx) {\n  fill_basic_data(event);\n\n  bpf_probe_read_kernel(&(event->mode), sizeof(event->mode),\n                        &(PT_REGS_PARM2(ctx)));\n\n  // bpf_trace_printk(\"Event: %d %d\\\\n\", event.object, event.mode);\n\n  lockevents.perf_submit(ctx, event, sizeof(PostgreSQLEvent));\n}\n\n/*\n * PostgreSQL: table_open\n * Parameter 1: Oid relationId\n * Parameter 2: LOCKMODE lockmode\n */\nint bpf_table_open(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_TABLE_OPEN};\n  bpf_probe_read_kernel(&(event.object), sizeof(event.object),\n                        &(PT_REGS_PARM1(ctx)));\n  handle_table_event(&event, ctx);\n  return 0;\n}\n\n/*\n *  ptype /o RangeVar\n *  type = struct RangeVar {\n *    0      |     4      NodeTag type;\n * XXX  4-byte hole\n *    8      |     8     char *catalogname;\n *   16      |     8     char *schemaname;\n *   24      |     8     char *relname;\n *   [...]\n */\ntypedef struct RangeVar {\n  u8 enumvalue;\n  char *catalogname;\n  char *schemaname;\n  char *relname;\n} RangeVar;\n\n/*\n * PostgreSQL: table_openrv\n * Parameter 1: const RangeVar *relation\n * Parameter 2: LOCKMODE lockmode\n */\nint bpf_table_openrv(struct pt_regs *ctx, RangeVar *relation) {\n  PostgreSQLEvent event = {.event_type = EVENT_TABLE_OPEN_RV};\n\n  bpf_probe_read_user_str(event.payload_str1, sizeof(event.payload_str1),\n                          (void *)relation->schemaname);\n  bpf_probe_read_user_str(event.payload_str2, sizeof(event.payload_str2),\n                          (void *)relation->relname);\n\n  handle_table_event(&event, ctx);\n\n  return 0;\n}\n\n/*\n * PostgreSQL: table_openrv_extended\n * Parameter 1: const RangeVar *relation\n * Parameter 2: LOCKMODE lockmode\n * Parameter 3: bool missing_ok\n */\nint bpf_table_openrv_extended(struct pt_regs *ctx, RangeVar *relation) {\n  PostgreSQLEvent event = {.event_type = EVENT_TABLE_OPEN_RV_EXTENDED};\n\n  bpf_probe_read_user_str(event.payload_str1, sizeof(event.payload_str1),\n                          (void *)relation->schemaname);\n  bpf_probe_read_user_str(event.payload_str2, sizeof(event.payload_str2),\n                          (void *)relation->relname);\n\n  handle_table_event(&event, ctx);\n\n  return 0;\n}\n\nint bpf_table_close(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_TABLE_CLOSE};\n\n  // Param 1 is a Relation struct\n  // The Oid rd_id is stored at byte 72 (PG 15.1)\n\n  // gdb: ptype /o Relation\n  //\n  // type = struct RelationData {\n  // /*    0      |    12 */    RelFileNode rd_node;\n  // /* XXX  4-byte hole  */\n  // /*   16      |     8 */    SMgrRelation rd_smgr;\n  // /*   24      |     4 */    int rd_refcnt;\n  // /*   28      |     4 */    BackendId rd_backend;\n  // /*   32      |     1 */    _Bool rd_islocaltemp;\n  // /*   33      |     1 */    _Bool rd_isnailed;\n  // /*   34      |     1 */    _Bool rd_isvalid;\n  // /*   35      |     1 */    _Bool rd_indexvalid;\n  // /*   36      |     1 */    _Bool rd_statvalid;\n  // /* XXX  3-byte hole  */\n  // /*   40      |     4 */    SubTransactionId rd_createSubid;\n  // /*   44      |     4 */    SubTransactionId rd_newRelfilenodeSubid;\n  // /*   48      |     4 */    SubTransactionId rd_firstRelfilenodeSubid;\n  // /*   52      |     4 */    SubTransactionId rd_droppedSubid;\n  // /*   56      |     8 */    Form_pg_class rd_rel;\n  // /*   64      |     8 */    TupleDesc rd_att;\n  // /*   72      |     4 */    Oid rd_id;\n  // [....]\n\n  char buffer[76];\n  bpf_probe_read_user(buffer, sizeof(buffer), (void *)PT_REGS_PARM1(ctx));\n  bpf_probe_read_kernel(&(event.object), sizeof(event.object), &(buffer[72]));\n\n  // Oid oid;\n  // bpf_probe_read_kernel(&oid, sizeof(oid), &(buffer[72]));\n  // bpf_probe_read_kernel(&(event.object), sizeof(event.object),\n  // &(PT_REGS_PARM1(ctx))); bpf_trace_printk(\"Oid: %d \\\\n\", oid);\n\n  handle_table_event(&event, ctx);\n  return 0;\n}\n\nstatic void fill_basic_data_and_submit(PostgreSQLEvent *event,\n                                       struct pt_regs *ctx) {\n  fill_basic_data(event);\n  lockevents.perf_submit(ctx, event, sizeof(PostgreSQLEvent));\n}\n\n/*\n * ====================================\n * Query handling\n * ====================================\n */\nint bpf_query_begin(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_QUERY_BEGIN};\n  bpf_probe_read_user_str(event.payload_str1, sizeof(event.payload_str1),\n                          (void *)PT_REGS_PARM1(ctx));\n  fill_basic_data_and_submit(&event, ctx);\n  return 0;\n}\n\n/*\n * Query return probe\n */\nint bpf_query_end(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_QUERY_END};\n  fill_basic_data_and_submit(&event, ctx);\n  return 0;\n}\n\n/*\n * ====================================\n * Error handling\n * ====================================\n */\nint bpf_errstart(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_ERROR};\n  fill_basic_data(&event);\n  bpf_probe_read_kernel(&event.mode, sizeof(event.mode),\n                        (void *)&(PT_REGS_PARM1(ctx)));\n\n  if (event.mode >= PGERROR_ERROR) {\n    lockevents.perf_submit(ctx, &event, sizeof(PostgreSQLEvent));\n  }\n\n  return 0;\n}\n\n/*\n * ====================================\n * Lock handling\n * ====================================\n */\n\n/*\n * PSQL: LockRelationOid\n * Parameter 1: Oid\n * Parameter 2: LOCKMODE\n */\nint bpf_lock_relation_oid(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_LOCK_RELATION_OID};\n  bpf_probe_read_kernel(&(event.object), sizeof(event.object),\n                        &(PT_REGS_PARM1(ctx)));\n\n#ifdef STACKTRACE_LOCK\n  event.stackid = stacks.get_stackid(ctx, BPF_F_USER_STACK);\n#endif\n\n  handle_table_event(&event, ctx);\n  return 0;\n}\n\n/*\n * PSQL: LockRelationOid - Return probe\n */\nint bpf_lock_relation_oid_end(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_LOCK_RELATION_OID_END};\n  fill_basic_data_and_submit(&event, ctx);\n  return 0;\n}\n\n/*\n * PSQL: UnlockRelationOid\n * Parameter 1: Oid\n * Parameter 2: LOCKMODE\n */\nint bpf_unlock_relation_oid(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_UNLOCK_RELATION_OID};\n  bpf_probe_read_kernel(&(event.object), sizeof(event.object),\n                        &(PT_REGS_PARM1(ctx)));\n  handle_table_event(&event, ctx);\n  return 0;\n}\n\n/*\n * Parse the LOCK Structure\n\n * PG 14.2\n * (gdb) ptype /o lock\n * type = struct LOCK {\n *    0      |    16 *    LOCKTAG tag;\n *   16      |     4 *    LOCKMASK grantMask;\n *   20      |     4 *    LOCKMASK waitMask;\n *   24      |    16 *    SHM_QUEUE procLocks;\n *   40      |    24 *    PROC_QUEUE waitProcs;\n *   64      |    40 *    int requested[10];\n *  104      |     4 *    int nRequested;\n *  108      |    40 *    int granted[10];\n *  148      |     4 *    int nGranted;\n *\n * (gdb) ptype /o LOCKTAG\n * type = struct LOCKTAG {\n *    0      |     4 *    uint32 locktag_field1; // Database OID (see\n SET_LOCKTAG_RELATION)\n *    4      |     4 *    uint32 locktag_field2; // Relation OID (see\n SET_LOCKTAG_RELATION)\n *    8      |     4 *    uint32 locktag_field3;\n *   12      |     2 *    uint16 locktag_field4;\n *   14      |     1 *    uint8 locktag_type;\n *   15      |     1 *    uint8 locktag_lockmethodid;\n */\nstatic void fill_lock_object(PostgreSQLEvent *event, void *param) {\n  char buffer[108];\n  bpf_probe_read_user(buffer, sizeof(buffer), param);\n  bpf_probe_read_kernel(&(event->object), sizeof(event->object), &(buffer[4]));\n  bpf_probe_read_kernel(&(event->requested), sizeof(event->requested),\n                        &(buffer[104]));\n}\n\n/*\n * PSQL: GrantLock\n * Parameter 1 LOCK\n * Parameter 2 PROCLOCK\n * Parameter 3 LOCKMODE\n */\nint bpf_lock_grant(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_LOCK_GRANTED};\n  bpf_probe_read_kernel(&(event.mode), sizeof(event.mode),\n                        &(PT_REGS_PARM3(ctx)));\n  fill_lock_object(&event, (void *)PT_REGS_PARM1(ctx));\n\n  if (event.object != 0) fill_basic_data_and_submit(&event, ctx);\n\n  return 0;\n}\n\n/*\n * PSQL: FastPathGrantRelationLock\n * Parameter 1 OID\n * Parameter 2 LOCKMODE\n */\nint bpf_lock_fastpath_grant(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_LOCK_GRANTED_FASTPATH};\n  bpf_probe_read_kernel(&(event.object), sizeof(event.object),\n                        &(PT_REGS_PARM1(ctx)));\n  bpf_probe_read_kernel(&(event.mode), sizeof(event.mode),\n                        &(PT_REGS_PARM2(ctx)));\n  fill_basic_data_and_submit(&event, ctx);\n  return 0;\n}\n\n/*\n * Local lock grant\n * Parameter 1: LOCALLOCK *locallock\n * Parameter 2: ResourceOwner owner\n *\n * PG 14\n *\n *  ptype /o locallock\n *  type = struct LOCALLOCK {\n *    0      |    20 *    LOCALLOCKTAG tag;\n *   20      |     4 *    uint32 hashcode;\n *   24      |     8 *    LOCK *lock;\n *   32      |     8 *    PROCLOCK *proclock;\n *   40      |     8 *    int64 nLocks;\n *   48      |     4 *    int numLockOwners;\n *   52      |     4 *    int maxLockOwners;\n *   56      |     8 *    LOCALLOCKOWNER *lockOwners;\n *   64      |     1 *    _Bool holdsStrongLockCount;\n *   65      |     1 *    _Bool lockCleared;\n * XXX  6-byte padding\n *\n * type = struct LOCALLOCKTAG {\n *    0      |    16 *    LOCKTAG lock; -- See LOCKTAG above\n *   16      |     4 *    LOCKMODE mode;\n *\n */\nstatic void fill_locallock_object(PostgreSQLEvent *event, void *param) {\n  char buffer[48];\n  bpf_probe_read_user(buffer, sizeof(buffer), param);\n  bpf_probe_read_kernel(&(event->object), sizeof(event->object), &(buffer[4]));\n  bpf_probe_read_kernel(&(event->lock_local_hold),\n                        sizeof(event->lock_local_hold), &(buffer[40]));\n  bpf_probe_read_kernel(&(event->mode), sizeof(event->mode), &(buffer[16]));\n}\n\n/*\n * PSQL: GrantLockLocal\n * Parameter 1 LOCALLOCK\n * Parameter 2 ResourceOwner\n */\nint bpf_lock_local_grant(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_LOCK_GRANTED_LOCAL};\n  fill_locallock_object(&event, (void *)PT_REGS_PARM1(ctx));\n\n  if (event.object != 0) fill_basic_data_and_submit(&event, ctx);\n\n  return 0;\n}\n\n/*\n * PSQL: UnGrantLock\n * Parameter 1 LOCK\n * Parameter 2 LOCKMODE\n */\nint bpf_lock_ungrant(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_LOCK_UNGRANTED};\n  bpf_probe_read_kernel(&(event.mode), sizeof(event.mode),\n                        &(PT_REGS_PARM2(ctx)));\n  fill_lock_object(&event, (void *)PT_REGS_PARM1(ctx));\n\n#ifdef STACKTRACE_UNLOCK\n  event.stackid = stacks.get_stackid(ctx, BPF_F_USER_STACK);\n#endif\n\n  if (event.object != 0) fill_basic_data_and_submit(&event, ctx);\n\n  return 0;\n}\n\n/*\n * PSQL: FastPathUnGrantRelationLock\n * Parameter 1 Oid\n * Parameter 2 LOCKMODE\n */\nint bpf_lock_fastpath_ungrant(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_LOCK_UNGRANTED_FASTPATH};\n  bpf_probe_read_kernel(&(event.object), sizeof(event.object),\n                        &(PT_REGS_PARM1(ctx)));\n  bpf_probe_read_kernel(&(event.mode), sizeof(event.mode),\n                        &(PT_REGS_PARM2(ctx)));\n\n#ifdef STACKTRACE_UNLOCK\n  event.stackid = stacks.get_stackid(ctx, BPF_F_USER_STACK);\n#endif\n\n  fill_basic_data_and_submit(&event, ctx);\n\n  return 0;\n}\n\n/*\n * PSQL: RemoveLocalLock\n * Parameter 1: LOCALLOCK\n */\nint bfp_local_lock_ungrant(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_LOCK_UNGRANTED_LOCAL};\n  fill_locallock_object(&event, (void *)PT_REGS_PARM1(ctx));\n\n  if (event.object != 0) fill_basic_data_and_submit(&event, ctx);\n\n  return 0;\n}\n\n/*\n * Deadlock detected\n * PSQL: DeadLockReport\n */\nint bpf_deadlock(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_DEADLOCK};\n#ifdef STACKTRACE_DEADLOCK\n  event.stackid = stacks.get_stackid(ctx, BPF_F_USER_STACK);\n#endif\n  fill_basic_data_and_submit(&event, ctx);\n  return 0;\n}\n\n/*\n * ====================================\n * Transaction handling\n * ====================================\n */\n\n/*\n * PSQL: StartTransaction\n */\nint bpf_transaction_begin(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_TRANSACTION_BEGIN};\n  fill_basic_data_and_submit(&event, ctx);\n  return 0;\n}\n\n/*\n * PSQL: CommitTransaction\n */\nint bpf_transaction_commit(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_TRANSACTION_COMMIT};\n  fill_basic_data_and_submit(&event, ctx);\n  return 0;\n}\n\n/*\n * PSQL: AbortTransaction\n */\nint bpf_transaction_abort(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_TRANSACTION_ABORT};\n  fill_basic_data_and_submit(&event, ctx);\n  return 0;\n}\n\n/*\n * ====================================\n * Process Invalidation Messages\n * ====================================\n */\n\n/*\n * PSQL: AcceptInvalidationMessages\n */\nint bpf_accept_invalidation_messages(struct pt_regs *ctx) {\n  PostgreSQLEvent event = {.event_type = EVENT_INVALIDATION_MESSAGES_ACCEPT};\n  fill_basic_data_and_submit(&event, ctx);\n  return 0;\n}"
  },
  {
    "path": "src/pg_lock_tracer/bpf/pg_lw_lock_tracer.c",
    "content": "// https://github.com/postgres/postgres/blob/a4adc31f6902f6fc29d74868e8969412fc590da9/src/include/storage/lwlock.h#L110\n\ntypedef enum LWLockMode {\n  LW_EXCLUSIVE,\n  LW_SHARED,\n  LW_WAIT_UNTIL_FREE /* A special mode used in PGPROC->lwWaitMode,\n                      * when waiting for lock to become free. Not\n                      * to be used as LWLockAcquire argument */\n} LWLockMode;\n\n/* Placeholder for auto generated defines */\n__DEFINES__\n\ntypedef struct LockEvent_t {\n  u32 pid;\n  u64 timestamp;\n  u32 event_type;\n\n  /* LWLock tranche name (see T_NAME / GetLWTrancheName()\n   * in lwlock.c) */\n  char tranche[255];\n\n  /* LWLockMode */\n  u32 mode;\n} LockEvent;\n\nBPF_PERF_OUTPUT(lockevents);\n\nstatic void fill_and_submit(struct pt_regs *ctx, LockEvent *event,\n                            uint64_t tranche_addr) {\n  bpf_probe_read_user_str(event->tranche, sizeof(event->tranche),\n                          (void *)tranche_addr);\n  event->pid = bpf_get_current_pid_tgid();\n  event->timestamp = bpf_ktime_get_ns();\n\n  // sudo cat /sys/kernel/debug/tracing/trace_pipe\n  // bpf_trace_printk(\"LW lock event for trance: %s\\\\n\", tranche);\n\n  lockevents.perf_submit(ctx, event, sizeof(LockEvent));\n}\n\n/*\n * Acquire a LW Lock\n * Arguments: TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), mode)\n */\nint lwlock_acquire(struct pt_regs *ctx) {\n  uint64_t tranche_addr = 0;\n  LWLockMode mode;\n\n  LockEvent event = {.event_type = EVENT_LOCK};\n\n  // The usdt does not support using bpf_usdt_readarg outside the main probe\n  // function See: https://github.com/iovisor/bcc/issues/2265\n  bpf_usdt_readarg(1, ctx, &tranche_addr);\n  bpf_usdt_readarg(2, ctx, &mode);\n\n  event.mode = mode;\n\n  fill_and_submit(ctx, &event, tranche_addr);\n  return 0;\n}\n\n/*\n * Release a LW Lock\n * Arguments: TRACE_POSTGRESQL_LWLOCK_RELEASE(T_NAME(lock))\n */\nint lwlock_release(struct pt_regs *ctx) {\n  uint64_t tranche_addr = 0;\n\n  LockEvent event = {.event_type = EVENT_UNLOCK};\n\n  bpf_usdt_readarg(1, ctx, &tranche_addr);\n\n  fill_and_submit(ctx, &event, tranche_addr);\n  return 0;\n}\n\n/*\n * Wait for a LW Lock\n * Arguments: TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode)\n */\nint lwlock_wait_start(struct pt_regs *ctx) {\n  uint64_t tranche_addr = 0;\n  LWLockMode mode;\n\n  LockEvent event = {.event_type = EVENT_WAIT_START};\n\n  // The usdt does not support using bpf_usdt_readarg outside the main probe\n  // function. See: https://github.com/iovisor/bcc/issues/2265\n  bpf_usdt_readarg(1, ctx, &tranche_addr);\n  bpf_usdt_readarg(2, ctx, &mode);\n\n  event.mode = mode;\n\n  fill_and_submit(ctx, &event, tranche_addr);\n  return 0;\n}\n\n/*\n * Wait for a LW Lock is done\n * Arguments: TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode)\n */\nint lwlock_wait_done(struct pt_regs *ctx) {\n  uint64_t tranche_addr = 0;\n  LWLockMode mode;\n\n  LockEvent event = {.event_type = EVENT_WAIT_DONE};\n\n  bpf_usdt_readarg(1, ctx, &tranche_addr);\n  bpf_usdt_readarg(2, ctx, &mode);\n\n  event.mode = mode;\n\n  fill_and_submit(ctx, &event, tranche_addr);\n  return 0;\n}\n\n/*\n * LWLock was successfully acquired when the caller specified no waiting\n * Arguments: TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE(T_NAME(lock), mode)\n */\nint lwlock_condacquire(struct pt_regs *ctx) {\n  uint64_t tranche_addr = 0;\n  LWLockMode mode;\n\n  LockEvent event = {.event_type = EVENT_COND_ACQUIRE};\n\n  bpf_usdt_readarg(1, ctx, &tranche_addr);\n  bpf_usdt_readarg(2, ctx, &mode);\n\n  event.mode = mode;\n\n  fill_and_submit(ctx, &event, tranche_addr);\n  return 0;\n}\n\n/*\n * LWLock was successfully acquired when the caller specified no waiting\n * Arguments: TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL(T_NAME(lock), mode)\n */\nint lwlock_condacquire_fail(struct pt_regs *ctx) {\n  uint64_t tranche_addr = 0;\n  LWLockMode mode;\n\n  LockEvent event = {.event_type = EVENT_COND_ACQUIRE_FAIL};\n\n  bpf_usdt_readarg(1, ctx, &tranche_addr);\n  bpf_usdt_readarg(2, ctx, &mode);\n\n  event.mode = mode;\n\n  fill_and_submit(ctx, &event, tranche_addr);\n  return 0;\n}\n\n/*\n * Acquire a LWLock or wait if already locked see LWLockAcquireOrWait\n * Arguments: TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT(T_NAME(lock), mode);\n */\nint lwlock_acquire_or_wait(struct pt_regs *ctx) {\n  uint64_t tranche_addr = 0;\n  LWLockMode mode;\n\n  LockEvent event = {.event_type = EVENT_LOCK_OR_WAIT};\n\n  bpf_usdt_readarg(1, ctx, &tranche_addr);\n  bpf_usdt_readarg(2, ctx, &mode);\n\n  event.mode = mode;\n\n  fill_and_submit(ctx, &event, tranche_addr);\n  return 0;\n}\n\n/*\n * Acquire a LWLock or wait if already locked (failed) see LWLockAcquireOrWait\n * Arguments: TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL(T_NAME(lock), mode);\n */\nint lwlock_acquire_or_wait_fail(struct pt_regs *ctx) {\n  uint64_t tranche_addr = 0;\n  LWLockMode mode;\n\n  LockEvent event = {.event_type = EVENT_LOCK_OR_WAIT_FAIL};\n\n  bpf_usdt_readarg(1, ctx, &tranche_addr);\n  bpf_usdt_readarg(2, ctx, &mode);\n\n  event.mode = mode;\n\n  fill_and_submit(ctx, &event, tranche_addr);\n  return 0;\n}"
  },
  {
    "path": "src/pg_lock_tracer/bpf/pg_row_lock_tracer.c",
    "content": "#include <uapi/linux/ptrace.h>\n\n/* Placeholder for auto generated defines */\n__DEFINES__\n\ntypedef struct RowLockEvent_t {\n  u32 pid;\n  u64 timestamp;\n  u32 event_type;\n\n  /* See RelFileNode - Oid is u32 */\n  u32 tablespace;\n  u32 database;\n  u32 relation;\n\n  /* LockTupleMode */\n  u8 locktuplemode;\n\n  /* LockWaitPolicy */\n  u8 lockwaitpolicy;\n\n  /* Locked tuple */\n  u32 blockid;\n  u16 offset;\n\n  /* TM_Result */\n  int lockresult;\n} RowLockEvent;\n\nBPF_PERF_OUTPUT(lockevents);\n\nstatic void fill_and_submit(struct pt_regs *ctx, RowLockEvent *event) {\n  event->pid = bpf_get_current_pid_tgid();\n  event->timestamp = bpf_ktime_get_ns();\n\n  // sudo cat /sys/kernel/debug/tracing/trace_pipe\n  // bpf_trace_printk(\"LW lock event for trance: %s\\\\n\", tranche);\n\n  lockevents.perf_submit(ctx, event, sizeof(RowLockEvent));\n}\n\n/*\n * Acquire a tuple lock\n *\n * Arguments:\n *   1. Relation relation (1st member RelFileNode)\n *   2. ItemPointer tid\n *   3. Snapshot snapshot,\n *   4. TupleTableSlot *slot,\n *   5. CommandId cid,\n *   6. LockTupleMode mode,\n *   7. LockWaitPolicy wait_policy,\n *   8. uint8 flags,\n *   9. TM_FailureData *tmfd\n *\n */\nint heapam_tuple_lock(struct pt_regs *ctx) {\n  RowLockEvent event = {.event_type = EVENT_LOCK_TUPLE};\n\n  /*\n   *    (gdb) ptype /o RelFileNode\n   *      0      |       4   Oid spcNode;\n   *      4      |       4   Oid dbNode;\n   *      8      |       4   Oid relNode;\n   */\n\n  char buffer_relation[12];\n  bpf_probe_read_user(buffer_relation, sizeof(buffer_relation),\n                      (void *)PT_REGS_PARM1(ctx));\n  bpf_probe_read_kernel(&(event.tablespace), sizeof(event.tablespace),\n                        &(buffer_relation[0]));\n  bpf_probe_read_kernel(&(event.database), sizeof(event.database),\n                        &(buffer_relation[4]));\n  bpf_probe_read_kernel(&(event.relation), sizeof(event.relation),\n                        &(buffer_relation[8]));\n\n  /* Locked tuple */\n  char buffer_item_pointer[6];\n  u16 bi_hi;\n  u16 bi_lo;\n\n  bpf_probe_read_user(buffer_item_pointer, sizeof(buffer_item_pointer),\n                      (void *)PT_REGS_PARM2(ctx));\n  bpf_probe_read_kernel(&(bi_hi), sizeof(bi_hi), &(buffer_item_pointer[0]));\n  bpf_probe_read_kernel(&(bi_lo), sizeof(bi_lo), &(buffer_item_pointer[2]));\n  bpf_probe_read_kernel(&(event.offset), sizeof(event.offset),\n                        &(buffer_item_pointer[4]));\n\n  /* See #define BlockIdGetBlockNumber(blockId) */\n  event.blockid = (bi_hi) << 16 | bi_lo;\n\n  /* Locking options */\n  bpf_probe_read_kernel(&(event.locktuplemode), sizeof(event.locktuplemode),\n                        &(PT_REGS_PARM6(ctx)));\n\n  /* Only the first six function parameters are passed via register. All\n   * remaining parameters are stored on the stack.\n   *\n   * See: System V Application Binary Interface—AMD64 Architecture Processor\n   * Supplement.\n   */\n  void *ptr = 0;\n  bpf_probe_read(&ptr, sizeof(ptr), (void *)(PT_REGS_SP(ctx) + (1 * 8)));\n  bpf_probe_read_kernel(&(event.lockwaitpolicy), sizeof(event.lockwaitpolicy),\n                        &ptr);\n\n  fill_and_submit(ctx, &event);\n  return 0;\n}\n\n/*\n * Acquire a tuple lock - Function done\n */\nint heapam_tuple_lock_end(struct pt_regs *ctx) {\n  RowLockEvent event = {.event_type = EVENT_LOCK_TUPLE_END};\n\n  event.lockresult = PT_REGS_RC(ctx);\n\n  fill_and_submit(ctx, &event);\n  return 0;\n}\n"
  },
  {
    "path": "src/pg_lock_tracer/bpf/pg_spinlock_delay_tracer.c",
    "content": "#include <uapi/linux/ptrace.h>\n\n#define MAX_STR_LEN 128\n\ntypedef struct SpinDelayStatus_t {\n  int spins;\n  int delays;\n  int cur_delay;\n  const char *file;\n  int line;\n  const char *func;\n} SpinDelayStatus;\n\ntypedef struct SpinDelayEvent_t {\n  u32 pid;\n  u64 timestamp;\n  int spins;\n  int delays;\n  int cur_delay;\n  int line;\n  char file[MAX_STR_LEN];\n  char func[MAX_STR_LEN];\n} SpinDelayEvent;\n\nBPF_PERF_OUTPUT(lockevents);\n\nint spin_delay(struct pt_regs *ctx) {\n  SpinDelayEvent event = {};\n  SpinDelayStatus status = {};\n  SpinDelayStatus *status_ptr = (SpinDelayStatus *)PT_REGS_PARM1(ctx);\n\n  event.pid = bpf_get_current_pid_tgid();\n  event.timestamp = bpf_ktime_get_ns();\n\n  if (!status_ptr) {\n    lockevents.perf_submit(ctx, &event, sizeof(SpinDelayEvent));\n    return 0;\n  }\n\n  bpf_probe_read_user(&status, sizeof(status), status_ptr);\n\n  event.spins = status.spins;\n  event.delays = status.delays;\n  event.cur_delay = status.cur_delay;\n  event.line = status.line;\n\n  if (status.file) {\n    bpf_probe_read_user_str(&event.file, sizeof(event.file), status.file);\n  }\n\n  if (status.func) {\n    bpf_probe_read_user_str(&event.func, sizeof(event.func), status.func);\n  }\n\n  lockevents.perf_submit(ctx, &event, sizeof(SpinDelayEvent));\n  return 0;\n}\n"
  },
  {
    "path": "src/pg_lock_tracer/helper.py",
    "content": "\"\"\"\nHelper classes\n\"\"\"\n\nimport os\n\nfrom pathlib import Path\n\nfrom bcc import BPF\n\n\nclass PostgreSQLLockHelper:\n    \"\"\"\n    # Defines taken from: src/include/storage/lockdefs.h\n    #\n    # NoLock is not a lock mode, but a flag value meaning \"don't get a lock\"\n    # define NoLock                  0\n    #\n    # define AccessShareLock         1   /* SELECT */\n    # define RowShareLock            2   /* SELECT FOR UPDATE/FOR SHARE */\n    # define RowExclusiveLock        3   /* INSERT, UPDATE, DELETE */\n    # define ShareUpdateExclusiveLock 4  /* VACUUM (non-FULL), ANALYZE, CREATE\n    #                                    * INDEX CONCURRENTLY */\n    # define ShareLock               5   /* CREATE INDEX (WITHOUT CONCURRENTLY) */\n    # define ShareRowExclusiveLock   6   /* like EXCLUSIVE MODE, but allows ROW\n    #                                    * SHARE */\n    # define ExclusiveLock           7   /* blocks ROW SHARE/SELECT...FOR UPDATE */\n    # define AccessExclusiveLock     8   /* ALTER TABLE, DROP TABLE, VACUUM FULL,\n    #                                    * and unqualified LOCK TABLE */\n    \"\"\"\n\n    locks = {}\n    locks[\"NoLock\"] = 0\n    locks[\"AccessShareLock\"] = 1\n    locks[\"RowShareLock\"] = 2\n    locks[\"RowExclusiveLock\"] = 3\n    locks[\"ShareUpdateExclusiveLock\"] = 4\n    locks[\"ShareLock\"] = 5\n    locks[\"ShareRowExclusiveLock\"] = 6\n    locks[\"ExclusiveLock\"] = 7\n    locks[\"AccessExclusiveLock\"] = 8\n\n    @staticmethod\n    def encode_locks_into_value(locks):\n        \"\"\"\n        Encode a list of lock types into a single value\n        \"\"\"\n        result = 0\n\n        for lock in locks:\n            lock_value = 1 << int(lock)\n            result |= lock_value\n\n        return result\n\n    @staticmethod\n    def decode_locks_from_value(encoded_value):\n        \"\"\"\n        Decode a value of locks into a list of locks\n        \"\"\"\n        result = []\n\n        for lock in range(0, 9):\n            lock_value = 1 << int(lock)\n\n            if encoded_value & lock_value == lock_value:\n                result.append(lock)\n\n        return result\n\n    @staticmethod\n    def lock_type_to_str(lock_type):\n        \"\"\"\n        Return the name of a lock based on the numeric value\n        \"\"\"\n        for lock_name, lock_numeric_value in PostgreSQLLockHelper.locks.items():\n            if lock_numeric_value == lock_type:\n                return lock_name\n\n        raise ValueError(f\"Unsupported lock type {lock_type}\")\n\n    @staticmethod\n    def lock_type_to_int(lock_name):\n        \"\"\"\n        Return the numeric value of a lock based on the name\n        \"\"\"\n\n        if lock_name not in PostgreSQLLockHelper.locks:\n            raise ValueError(f\"Unknown lock type {lock_name}\")\n\n        return PostgreSQLLockHelper.locks[lock_name]\n\n\nclass BPFHelper:\n    # The size of the kernel ring buffer\n    page_cnt = 2048\n\n    @staticmethod\n    def enum_to_defines(enum_instance, prefix):\n        \"\"\"\n        Convert a IntEnum into C '#define' statements\n        \"\"\"\n        result = \"\"\n\n        for instance in enum_instance:\n            result += f\"#define {prefix}_{instance.name} {instance.value}\\n\"\n\n        return result\n\n    @staticmethod\n    def read_bpf_program(program_name):\n        \"\"\"\n        Load the BPF program from a file and return it as a string.\n        \"\"\"\n        program_file = Path(__file__).parent / \"bpf\" / program_name\n\n        if not os.path.exists(program_file):\n            raise ValueError(f\"BPF program file not found {program_file}\")\n\n        with program_file.open(\"r\") as bpf_program:\n            return bpf_program.read()\n\n    @staticmethod\n    def check_pid_exe(pids, executable):\n        \"\"\"\n        Do the given PIDs belong to the executable\n        \"\"\"\n        if not pids:\n            return\n\n        for pid in pids:\n            if not os.path.isdir(f\"/proc/{pid}\"):\n                raise ValueError(\n                    f\"/proc entry for pid {pid} not found, does the process exist?\"\n                )\n\n            binary = os.readlink(f\"/proc/{pid}/exe\")\n\n            if binary != executable:\n                raise ValueError(\n                    f\"Pid {pid} does not belong to binary {executable}. Executable is {binary}\"\n                )\n\n    @staticmethod\n    def register_ebpf_probe(\n        path, bpf_instance, function_regex, bpf_fn_name, verbose, probe_on_enter=True\n    ):\n        \"\"\"\n        Register a BPF probe\n        \"\"\"\n        addresses = set()\n        func_and_addr = BPF.get_user_functions_and_addresses(path, function_regex)\n\n        if not func_and_addr:\n            raise ValueError(f\"Unable to locate function {function_regex}\")\n\n        # Handle address duplicates\n        for function, address in func_and_addr:\n            if address in addresses:\n                continue\n            addresses.add(address)\n\n            if probe_on_enter:\n                bpf_instance.attach_uprobe(name=path, sym=function, fn_name=bpf_fn_name)\n                if verbose:\n                    print(f\"Attaching to {function} at address {address} on enter\")\n            else:\n                bpf_instance.attach_uretprobe(\n                    name=path, sym=function, fn_name=bpf_fn_name\n                )\n                if verbose:\n                    print(f\"Attaching to {function} at address {address} on return\")\n"
  },
  {
    "path": "src/pg_lock_tracer/oid_resolver.py",
    "content": "\"\"\"Resolve PostgreSQL OIDs to names and cache the result\"\"\"\n\nimport sys\n\nfrom urllib.parse import urlparse\n\nimport psycopg2\n\n\nclass OIDResolver:\n    def __init__(self, connection_url):\n        self.connection_url = connection_url\n        self.cache = {}\n        self.connection = None\n        self.cur = None\n        self.connect()\n\n    def connect(self):\n        \"\"\"\n        Open the database connection\n        \"\"\"\n        connection_url_parsed = urlparse(self.connection_url)\n        username = connection_url_parsed.username\n        password = connection_url_parsed.password\n        database = connection_url_parsed.path[1:]\n        hostname = connection_url_parsed.hostname\n        port = connection_url_parsed.port\n\n        try:\n            self.connection = psycopg2.connect(\n                database=database,\n                user=username,\n                password=password,\n                host=hostname,\n                port=port,\n            )\n            self.connection.set_session(autocommit=True)\n            self.cur = self.connection.cursor()\n\n            # Warmup cache\n            self.fetch_all_oids()\n        except psycopg2.OperationalError as error:\n            print(f\"Unable to connect to the database {self.connection_url}\")\n            print(f\"{error}\")\n            sys.exit(1)\n\n    def disconnect(self):\n        \"\"\"\n        Close the database connection.\n        \"\"\"\n        if self.cur:\n            self.cur.close()\n            self.cur = None\n\n        if self.connection:\n            self.connection.close()\n            self.connection = None\n\n    def fetch_all_oids(self):\n        \"\"\"\n        Fetch all Oid mappings from the catalog and cache them. This\n        is done because:\n\n        (1) Cache Oid cache lookups have to be fast and we want\n            a warm cache.\n\n        (2) Operations such as DROP delete objects from the database.\n            Fetching the oid mapping afterwards is not possible.\n        \"\"\"\n\n        select_stmt = \"\"\"\n        SELECT n.nspname, c.relname, c.oid \n        FROM pg_namespace n\n        JOIN pg_class c ON n.oid = c.relnamespace\n        \"\"\"\n\n        self.cur.execute(select_stmt)\n\n        oids = self.cur.fetchall()\n\n        for result_row in oids:\n            oid = result_row[2]\n            name = f\"{result_row[0]}.{result_row[1]}\"\n            self.cache[oid] = name\n\n    def fetch_oid_from_db(self, oid):\n        \"\"\"\n        Resolve the given OID into a name\n        \"\"\"\n\n        select_stmt = \"\"\"\n        SELECT n.nspname, c.relname\n        FROM pg_namespace n\n        JOIN pg_class c ON n.oid = c.relnamespace\n        WHERE c.oid = %s;\n        \"\"\"\n\n        oid = str(oid)\n\n        try:\n            self.cur.execute(\n                select_stmt,\n                [\n                    oid,\n                ],\n            )\n\n            result_row = self.cur.fetchone()\n\n            # Unable to get name, return Oid instead\n            if result_row is None:\n                return f\"Oid {oid}\"\n\n            name = f\"{result_row[0]}.{result_row[1]}\"\n\n            # Cache result\n            self.cache[oid] = name\n\n            return name\n        except psycopg2.Error as error:\n            print(f\"Error while executing SQL statement: {error}\")\n            print(f\"pgerror: {error.pgerror}\")\n            print(f\"pgcode: {error.pgcode}\")\n            return \"\"\n\n    def resolve_oid(self, oid):\n        \"\"\"\n        Resolve the given OID into a name.\n        \"\"\"\n\n        # OID cache hit\n        if oid in self.cache:\n            return self.cache[oid]\n\n        # OID cache miss\n        return self.fetch_oid_from_db(oid)\n"
  },
  {
    "path": "src/pg_lock_tracer/pg_lock_tracer.py",
    "content": "#!/usr/bin/env python3\n#\n# PostgreSQL lock tracer\n#\n# This tool traces the lock operations that PostgreSQL performs.\n#\n# Unfortunately, PostgreSQL does not provide USDT probes for\n# these locks. Therefore BPF, UProbes, and parameter parsing\n# is used to trace these events.\n###############################################\n\nimport os\nimport sys\nimport json\nimport argparse\n\nfrom abc import ABC\nfrom enum import IntEnum, auto, unique\nfrom bcc import BPF\nfrom prettytable import PrettyTable\n\nfrom pg_lock_tracer import __version__\nfrom pg_lock_tracer.oid_resolver import OIDResolver\nfrom pg_lock_tracer.helper import PostgreSQLLockHelper, BPFHelper\n\nEXAMPLES = \"\"\"\n\nusage examples:\n# Trace use binary '/home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres' for tracing and trace pid 1234\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234\n\n# Trace two PIDs\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -p 5678\n\n# Be verbose\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -v \n\n# Use the given db connection to access the catalog of PID 1234 to resolve OIDs\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -r 1234:psql://jan@localhost/test2\n\n# Output in JSON format\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -j\n\n# Print stacktrace on deadlock\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -s DEADLOCK\n\n# Print stacktrace for locks and deadlocks\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -s LOCK DEADLOCK\n\n# Trace only Transaction and Query related events\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -t TRANSACTION QUERY\n\n# Write the output into file 'trace'\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 -o trace\n\n# Show statistics about locks\npg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres -p 1234 --statistics\n\"\"\"\n\n\nclass TraceEvents(IntEnum):\n    \"\"\"\n    Events to trace\n    \"\"\"\n\n    TRANSACTION = auto()\n    QUERY = auto()\n    TABLE = auto()\n    LOCK = auto()\n    INVALIDATION = auto()\n    ERROR = auto()\n\n\nparser = argparse.ArgumentParser(\n    description=\"\",\n    formatter_class=argparse.RawDescriptionHelpFormatter,\n    epilog=EXAMPLES,\n)\nparser.add_argument(\n    \"-V\",\n    \"--version\",\n    action=\"version\",\n    version=f\"{parser.prog} ({__version__})\",\n)\nparser.add_argument(\"-v\", \"--verbose\", action=\"store_true\", help=\"be verbose\")\nparser.add_argument(\n    \"-j\", \"--json\", action=\"store_true\", help=\"generate output as JSON data\"\n)\nparser.add_argument(\n    \"-p\",\n    \"--pid\",\n    type=int,\n    nargs=\"+\",\n    action=\"extend\",\n    dest=\"pids\",\n    metavar=\"PID\",\n    help=\"the pid(s) to trace\",\n)\nparser.add_argument(\n    \"-x\",\n    \"--exe\",\n    type=str,\n    required=True,\n    dest=\"path\",\n    metavar=\"PATH\",\n    help=\"path to binary\",\n)\nparser.add_argument(\n    \"-r\",\n    \"--oid-resolver\",\n    type=str,\n    action=\"extend\",\n    default=[],\n    nargs=\"*\",\n    dest=\"oid_resolver_urls\",\n    metavar=\"OIDResolver\",\n    help=\"OID resolver for a PID. The resolver has to be specified in format <PID:database-url>\",\n)\nparser.add_argument(\n    \"-s\",\n    \"--stacktrace\",\n    type=str,\n    dest=\"stacktrace\",\n    action=\"extend\",\n    default=None,\n    nargs=\"*\",\n    choices=[\"DEADLOCK\", \"LOCK\", \"UNLOCK\"],\n    help=\"print stacktrace on every of these events\",\n)\nparser.add_argument(\n    \"-t\",\n    \"--trace\",\n    type=str,\n    dest=\"trace\",\n    action=\"extend\",\n    default=None,\n    nargs=\"*\",\n    choices=[event.name for event in TraceEvents],\n    help=\"events to trace (default: All events are traced)\",\n)\nparser.add_argument(\n    \"-o\",\n    \"--output\",\n    type=str,\n    dest=\"output_file\",\n    default=None,\n    help=\"write the trace into output file\",\n)\nparser.add_argument(\"--statistics\", action=\"store_true\", help=\"print lock statistics\")\nparser.add_argument(\n    \"-d\",\n    \"--dry-run\",\n    action=\"store_true\",\n    help=\"compile and load the BPF program but exit afterward\",\n)\n\n\n@unique\nclass Events(IntEnum):\n    TABLE_OPEN = 1\n    TABLE_OPEN_RV = 2\n    TABLE_OPEN_RV_EXTENDED = 3\n    TABLE_CLOSE = 4\n    ERROR = 5\n    QUERY_BEGIN = 20\n    QUERY_END = 21\n    LOCK_RELATION_OID = 30\n    LOCK_RELATION_OID_END = 31\n    UNLOCK_RELATION_OID = 32\n    LOCK_GRANTED = 33\n    LOCK_GRANTED_FASTPATH = 34\n    LOCK_GRANTED_LOCAL = 35\n    LOCK_UNGRANTED = 36\n    LOCK_UNGRANTED_FASTPATH = 37\n    LOCK_UNGRANTED_LOCAL = 38\n    TRANSACTION_BEGIN = 40\n    TRANSACTION_COMMIT = 41\n    TRANSACTION_ABORT = 42\n    INVALIDATION_MESSAGES_ACCEPT = 50\n    # Events over 1000 are handled regardless of any pid filter\n    GLOBAL = 1000\n    DEADLOCK = 1001\n\n\n# From elog.h\n@unique\nclass PGError(IntEnum):\n    ERROR = 21\n    FATAL = 22\n    PANIC = 23\n\n\nclass LockStatisticsEntry:\n    def __init__(self) -> None:\n        # The number of requested locks\n        self._lock_count = 0\n\n        # The total time spend for lock requests\n        self._lock_time_ns = 0\n\n        # A list with the requested locks\n        self._requested_locks = []\n\n    @property\n    def lock_count(self):\n        return self._lock_count\n\n    @lock_count.setter\n    def lock_count(self, value):\n        self._lock_count = value\n\n    @property\n    def lock_time_ns(self):\n        return self._lock_time_ns\n\n    @lock_time_ns.setter\n    def lock_time_ns(self, value):\n        self._lock_time_ns = value\n\n    @property\n    def requested_locks(self):\n        return self._requested_locks\n\n    @requested_locks.setter\n    def requested_locks(self, lock_type):\n        self._requested_locks.append(lock_type)\n\n\nclass PGLockTraceOutput(ABC):\n    def __init__(self) -> None:\n        super().__init__()\n        self.statistics = {}\n        self.bpf_instance = None\n        self.bpf_stacks = None\n        self.output_file = None\n        self.oid_resolvers = None\n        self.pids = None\n        # Variables for lock timing\n        self.last_lock_request_time = {}\n        self.last_lock_relation = {}\n\n    def set_context(\n        self, bpf_instance, bpf_stacks, output_file, oid_resolvers, pids\n    ) -> None:\n        \"\"\"\n        Set the needed context variables\n        \"\"\"\n        self.bpf_instance = bpf_instance\n        self.bpf_stacks = bpf_stacks\n        self.output_file = output_file\n        self.oid_resolvers = oid_resolvers\n        self.pids = pids\n\n    def print_event(self, _cpu, data, _size):\n        \"\"\"\n        Handle the output of the given event. Subclasses will implement\n        the concrete logic.\n        \"\"\"\n\n    def update_statistics(self, event, oid_value):\n        \"\"\"\n        Add the lock call to the statistics and measure lock request time\n        \"\"\"\n        if event.event_type == Events.LOCK_RELATION_OID:\n            if oid_value not in self.statistics:\n                self.statistics[oid_value] = LockStatisticsEntry()\n\n            statistics_entry = self.statistics.get(oid_value)\n            statistics_entry.lock_count += 1\n            statistics_entry.requested_locks = event.mode\n\n            self.last_lock_request_time[event.pid] = event.timestamp\n            self.last_lock_relation[event.pid] = oid_value\n\n        if event.event_type == Events.LOCK_RELATION_OID_END:\n            lock_relation = self.last_lock_relation[event.pid]\n            statistics_entry = self.statistics.get(lock_relation)\n            statistics_entry.lock_time_ns += self.get_lock_wait_time(event)\n            self.last_lock_relation[event.pid] = None\n\n    def get_lock_wait_time(self, event):\n        \"\"\"\n        Get the last lock wait time (LOCK_RELATION_OID updates\n        last_lock_request_time).\n\n        This method should be called on LOCK_RELATION_OID_END.\n        \"\"\"\n        if event.event_type != Events.LOCK_RELATION_OID_END:\n            return None\n\n        return event.timestamp - self.last_lock_request_time[event.pid]\n\n    def print_statistics(self):\n        \"\"\"\n        Print lock statistics\n        \"\"\"\n        print(\"\\nLock statistics:\\n================\")\n\n        # Oid lock statistics\n        print(\"\\nLocks per OID\")\n        table = PrettyTable([\"Lock Name\", \"Requests\", \"Total Lock Request Time (ns)\"])\n\n        sorted_keys = sorted(\n            self.statistics.keys(),\n            key=lambda key: self.statistics.get(key).lock_count,\n            reverse=True,\n        )\n\n        for key in sorted_keys:\n            statistics = self.statistics[key]\n            table.add_row([key, statistics.lock_count, statistics.lock_time_ns])\n\n        print(table)\n\n        # Lock type statistics\n        print(\"\\nLock types\")\n        table = PrettyTable([\"Lock Type\", \"Number of requested locks\"])\n\n        # Map: Key = Lock type, Value = Number of requested locks\n        requested_locks = {}\n\n        # Gather per lock type statistics\n        for statistics in self.statistics.values():\n            for lock_type in statistics.requested_locks:\n                locks = requested_locks.get(lock_type, 0) + 1\n                requested_locks[lock_type] = locks\n\n        # Print statistics\n        for lock_type in sorted(requested_locks):\n            locks = requested_locks[lock_type]\n            lock_name = PostgreSQLLockHelper.lock_type_to_str(lock_type)\n            table.add_row([lock_name, locks])\n\n        print(table)\n\n    def handle_output_line(self, line):\n        \"\"\"\n        Handle a output line\n        \"\"\"\n        if self.output_file:\n            self.output_file.write(line + \"\\n\")\n        else:\n            print(line)\n\n\nclass PGLockTraceOutputHuman(PGLockTraceOutput):\n    # pylint: disable=too-many-branches, too-many-statements\n    def print_event(self, _cpu, data, _size):\n        \"\"\"\n        Print event in a human readable format\n        \"\"\"\n        event = self.bpf_instance[\"lockevents\"].event(data)\n\n        if (\n            self.pids\n            and event.pid not in self.pids\n            and event.event_type < Events.GLOBAL\n        ):\n            return\n\n        print_prefix = f\"{event.timestamp} [Pid {event.pid}]\"\n\n        # Resolve the OID to a name\n        if event.object > 0:\n            tablename = event.object\n\n        # Resolve the OID to a table name\n        if event.pid in self.oid_resolvers and event.object:\n            resolver = self.oid_resolvers[event.pid]\n            oid_value = resolver.resolve_oid(event.object)\n            tablename = f\"{tablename} ({oid_value})\"\n            self.update_statistics(event, oid_value)\n        else:\n            self.update_statistics(event, event.object)\n\n        output = None\n        if event.event_type == Events.TABLE_OPEN:\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            output = f\"{print_prefix} Table open {tablename} {lock_type}\"\n        elif event.event_type in (Events.TABLE_OPEN_RV, Events.TABLE_OPEN_RV_EXTENDED):\n            # Table is opened using a (string) range value\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            schema = event.payload_str1.decode(\"utf-8\")\n            table = event.payload_str2.decode(\"utf-8\")\n            tablename = f\"{schema}.{table}\"\n            output = (\n                f\"{print_prefix} Table open (by range value) {tablename} {lock_type}\"\n            )\n        elif event.event_type == Events.TABLE_CLOSE:\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            output = f\"{print_prefix} Table close {tablename} {lock_type}\"\n        elif event.event_type == Events.LOCK_RELATION_OID:\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            output = f\"{print_prefix} Lock object {tablename} {lock_type}\"\n        elif event.event_type == Events.LOCK_RELATION_OID_END:\n            lock_time = self.get_lock_wait_time(event)\n            output = f\"{print_prefix} Lock was acquired in {lock_time} ns\"\n        elif event.event_type == Events.UNLOCK_RELATION_OID:\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            output = f\"{print_prefix} Unlock relation {tablename} {lock_type}\"\n        elif event.event_type == Events.LOCK_GRANTED:\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            output = (\n                f\"{print_prefix} Lock granted {tablename} {lock_type} \"\n                f\"(Requested locks {event.requested})\"\n            )\n        elif event.event_type == Events.LOCK_GRANTED_FASTPATH:\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            output = f\"{print_prefix} Lock granted (fastpath) {tablename} {lock_type}\"\n        elif event.event_type == Events.LOCK_GRANTED_LOCAL:\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            output = (\n                f\"{print_prefix} Lock granted (local) {tablename} {lock_type} \"\n                f\"(Already hold local {event.lock_local_hold})\"\n            )\n        elif event.event_type == Events.LOCK_UNGRANTED:\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            output = (\n                f\"{print_prefix} Lock ungranted {tablename} {lock_type} \"\n                f\"(Requested locks {event.requested})\"\n            )\n        elif event.event_type == Events.LOCK_UNGRANTED_FASTPATH:\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            output = f\"{print_prefix} Lock ungranted (fastpath) {tablename} {lock_type}\"\n        elif event.event_type == Events.LOCK_UNGRANTED_LOCAL:\n            lock_type = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n            output = (\n                f\"{print_prefix} Lock ungranted (local) {tablename} {lock_type} \"\n                f\"(Hold local {event.lock_local_hold})\"\n            )\n        elif event.event_type == Events.INVALIDATION_MESSAGES_ACCEPT:\n            output = f\"{print_prefix} Accept invalidation messages\"\n        elif event.event_type == Events.ERROR:\n            pgerror_value = PGError(event.mode).name\n            output = f\"{print_prefix} Error occurred servity: {pgerror_value}\"\n        elif event.event_type == Events.QUERY_BEGIN:\n            query = event.payload_str1.decode(\"utf-8\")\n            output = f\"{print_prefix} Query begin '{query}'\"\n        elif event.event_type == Events.QUERY_END:\n            output = f\"{print_prefix} Query done\\n\"\n        elif event.event_type == Events.TRANSACTION_BEGIN:\n            output = f\"{print_prefix} Transaction begin\"\n        elif event.event_type == Events.TRANSACTION_COMMIT:\n            output = f\"{print_prefix} Transaction commit\"\n        elif event.event_type == Events.TRANSACTION_ABORT:\n            output = f\"{print_prefix} Transaction abort\"\n        elif event.event_type == Events.DEADLOCK:\n            output = f\"{print_prefix} DEADLOCK DETECTED\"\n        else:\n            raise ValueError(f\"Unsupported event type {event.event_type}\")\n\n        self.handle_output_line(output)\n        self.print_stacktace_if_available(event)\n\n    def print_stacktace_if_available(self, event):\n        \"\"\"\n        Print the stacktrace of an event if available\n        \"\"\"\n        if event.stackid == 0 or self.bpf_stacks is None:\n            return\n\n        if event.stackid < 0:\n            print(\n                \"Error stack is missing. Try to increase BPF_STACK_TRACE buffer size.\"\n            )\n        else:\n            for frame in self.bpf_stacks.walk(event.stackid):\n                line = self.bpf_instance.sym(\n                    frame, event.pid, show_offset=True, show_module=True\n                )\n                line = line.decode(\"utf-8\")\n                # Get line with: 'gdb info line *(symbol+0x1111)'\n                line = f\"\\t{line}\"\n                self.handle_output_line(line)\n\n\nclass PGLockTraceOutputJSON(PGLockTraceOutput):\n    def print_event(self, _cpu, data, _size):\n        \"\"\"\n        Print event in JSON format\n        \"\"\"\n        event = self.bpf_instance[\"lockevents\"].event(data)\n\n        if (\n            self.pids\n            and event.pid not in self.pids\n            and event.event_type < Events.GLOBAL\n        ):\n            return\n\n        output = {}\n        output[\"timestamp\"] = event.timestamp\n        output[\"pid\"] = event.pid\n        output[\"event\"] = Events(event.event_type).name\n\n        if event.event_type in (\n            Events.TABLE_OPEN,\n            Events.TABLE_OPEN_RV,\n            Events.TABLE_OPEN_RV_EXTENDED,\n            Events.TABLE_CLOSE,\n            Events.LOCK_RELATION_OID,\n            Events.UNLOCK_RELATION_OID,\n            Events.LOCK_GRANTED,\n            Events.LOCK_GRANTED_FASTPATH,\n            Events.LOCK_GRANTED_LOCAL,\n            Events.LOCK_UNGRANTED,\n            Events.LOCK_UNGRANTED_FASTPATH,\n            Events.LOCK_UNGRANTED_LOCAL,\n        ):\n            output[\"lock_type\"] = PostgreSQLLockHelper.lock_type_to_str(event.mode)\n\n        # Resolve OID to tablename\n        if event.pid in self.oid_resolvers and event.object:\n            resolver = self.oid_resolvers[event.pid]\n            oid_value = resolver.resolve_oid(event.object)\n            output[\"table\"] = oid_value\n            self.update_statistics(event, oid_value)\n        else:\n            self.update_statistics(event, event.object)\n\n        # Resolve the OID to a name\n        if event.object:\n            output[\"oid\"] = event.object\n\n        if event.event_type == Events.ERROR:\n            pgerror_value = PGError(event.mode).name\n            output[\"servity\"] = pgerror_value\n        elif event.event_type == Events.QUERY_BEGIN:\n            output[\"query\"] = event.payload_str1.decode(\"utf-8\")\n        elif event.event_type in (Events.TABLE_OPEN_RV, Events.TABLE_OPEN_RV_EXTENDED):\n            # Table is opened using a (string) range value\n            schema = event.payload_str1.decode(\"utf-8\")\n            table = event.payload_str2.decode(\"utf-8\")\n            output[\"table\"] = f\"{schema}.{table}\"\n        elif event.event_type == Events.LOCK_GRANTED_LOCAL:\n            output[\"lock_local_hold\"] = event.lock_local_hold\n        elif event.event_type == Events.LOCK_RELATION_OID_END:\n            lock_time = self.get_lock_wait_time(event)\n            output[\"lock_time\"] = lock_time\n\n        self.add_stacktrace_if_available(output, event)\n\n        self.handle_output_line(json.dumps(output))\n\n    def add_stacktrace_if_available(self, output, event):\n        \"\"\"\n        Add a stacktrace to the JSON structure if available\n        \"\"\"\n        if event.stackid == 0 or self.bpf_stacks is None:\n            return\n\n        if event.stackid < 0:\n            output[\"stacktrace\"] = \"MISSING\"\n        else:\n            lines = []\n\n            # Get stacktrace symbol with module\n            for frame in self.bpf_stacks.walk(event.stackid):\n                line = self.bpf_instance.sym(\n                    frame, event.pid, show_offset=True, show_module=True\n                )\n                lines.append(line.decode(\"utf-8\"))\n\n            # Merge lines into a single string\n            stacktrace = \", \".join(lines)\n            output[\"stacktrace\"] = stacktrace\n\n\nclass PGLockTracer:\n    def __init__(self, prog_args):\n        self.bpf_instance = None\n        self.bpf_stacks = None\n        self.output_file = None\n        self.output_class = None\n        self.args = prog_args\n\n        # A map of OID resolvers. One resolver per PID is needed\n        # because the Oid depend on the catalog of the database.\n        self.oid_resolvers = {}\n\n        for oid_resolver_url in self.args.oid_resolver_urls:\n            if \":\" not in oid_resolver_url:\n                raise ValueError(\n                    f\"Resolver URL has to be in format: 'PID:URL' ({oid_resolver_url} was provided)\"\n                )\n\n            split_url = oid_resolver_url.split(\":\", 1)\n            resolver_pid = int(split_url[0])\n            database_url = split_url[1]\n\n            if resolver_pid not in self.args.pids:\n                print(\n                    f\"Specified resolver for PID {resolver_pid}, but PID is not monitored\"\n                )\n                sys.exit(1)\n\n            if self.args.verbose:\n                print(f\"Add resolver for PID {resolver_pid} with URL {database_url}\")\n\n            oid_resolver = OIDResolver(database_url)\n            self.oid_resolvers[resolver_pid] = oid_resolver\n\n        # Belong the processes to the binary?\n        BPFHelper.check_pid_exe(self.args.pids, self.args.path)\n\n        # Does the output file already exists?\n        if self.args.output_file and os.path.exists(self.args.output_file):\n            raise ValueError(f\"Output file {self.args.output_file} already exists\")\n\n    @staticmethod\n    def generate_c_defines(stacktrace_events, verbose):\n        \"\"\"\n        Create C defines from python enums\n        \"\"\"\n        enum_defines = BPFHelper.enum_to_defines(Events, \"EVENT\")\n        error_defines = BPFHelper.enum_to_defines(PGError, \"PGERROR\")\n        defines = enum_defines + error_defines\n\n        # Print stacktrace for each lock\n        if stacktrace_events and \"LOCK\" in stacktrace_events:\n            defines += \"#define STACKTRACE_LOCK\\n\"\n            if verbose:\n                print(\"Print stacktrace on each lock event\")\n\n        # Print stacktrace for each unlock\n        if stacktrace_events and \"UNLOCK\" in stacktrace_events:\n            defines += \"#define STACKTRACE_UNLOCK\\n\"\n            if verbose:\n                print(\"Print stacktrace on each unlock event\")\n\n        # Print stacktrace on deadlock\n        if stacktrace_events and \"DEADLOCK\" in stacktrace_events:\n            defines += \"#define STACKTRACE_DEADLOCK\\n\"\n            if verbose:\n                print(\"Print stacktrace on each deadlock\")\n\n        return defines\n\n    def init(self):\n        \"\"\"\n        Init the PostgreSQL lock tracer\n        \"\"\"\n\n        defines = PGLockTracer.generate_c_defines(\n            self.args.stacktrace, self.args.verbose\n        )\n        bpf_program = BPFHelper.read_bpf_program(\"pg_lock_tracer.c\")\n        bpf_program_final = bpf_program.replace(\"__DEFINES__\", defines)\n\n        if self.args.verbose:\n            print(bpf_program_final)\n\n        # Disable warnings like\n        # 'warning: '__HAVE_BUILTIN_BSWAP32__' macro redefined [-Wmacro-redefined]'\n        bpf_cflags = [\"-Wno-macro-redefined\"] if not self.args.verbose else []\n\n        print(\"===> Compiling BPF program\")\n        self.bpf_instance = BPF(text=bpf_program_final, cflags=bpf_cflags)\n\n        print(\"===> Attaching BPF probes\")\n        self.attach_probes()\n\n        # Stack traces requested?\n        if self.args.stacktrace:\n            self.bpf_stacks = self.bpf_instance.get_table(\"stacks\")\n\n        # Open file for output if provided\n        if self.args.output_file:\n            # pylint: disable=consider-using-with\n            self.output_file = open(self.args.output_file, \"w\", encoding=\"utf-8\")\n            if not self.output_file.writable():\n                raise ValueError(\n                    f\"Output file {self.args.output_file} is not writeable\"\n                )\n\n        # Output as human readable text or as json?\n        self.output_class = (\n            PGLockTraceOutputJSON() if self.args.json else PGLockTraceOutputHuman()\n        )\n\n        # Init the output class\n        self.output_class.set_context(\n            self.bpf_instance,\n            self.bpf_stacks,\n            self.output_file,\n            self.oid_resolvers,\n            self.args.pids,\n        )\n\n        # Open the event queue\n        self.bpf_instance[\"lockevents\"].open_perf_buffer(\n            self.output_class.print_event, page_cnt=BPFHelper.page_cnt\n        )\n\n    def attach_probes(self):\n        \"\"\"\n        Attach BPF probes\n        \"\"\"\n        # Transaction probes\n        if self.args.trace is None or TraceEvents.TRANSACTION.name in self.args.trace:\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^StartTransaction$\",\n                \"bpf_transaction_begin\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^CommitTransaction$\",\n                \"bpf_transaction_commit\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^AbortTransaction$\",\n                \"bpf_transaction_abort\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^DeadLockReport$\",\n                \"bpf_deadlock\",\n                self.args.verbose,\n            )\n\n        # Query probes\n        if self.args.trace is None or TraceEvents.QUERY.name in self.args.trace:\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^exec_simple_query$\",\n                \"bpf_query_begin\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^exec_simple_query$\",\n                \"bpf_query_end\",\n                self.args.verbose,\n                False,\n            )\n\n        # Table probes\n        if self.args.trace is None or TraceEvents.TABLE.name in self.args.trace:\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^table_open$\",\n                \"bpf_table_open\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^table_openrv$\",\n                \"bpf_table_openrv\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^table_openrv_extended$\",\n                \"bpf_table_openrv_extended\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^table_close$\",\n                \"bpf_table_close\",\n                self.args.verbose,\n            )\n\n        # Lock probes\n        if self.args.trace is None or TraceEvents.LOCK.name in self.args.trace:\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^LockRelationOid$\",\n                \"bpf_lock_relation_oid\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^LockRelationOid$\",\n                \"bpf_lock_relation_oid_end\",\n                self.args.verbose,\n                False,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^UnlockRelationOid$\",\n                \"bpf_unlock_relation_oid\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^GrantLock$\",\n                \"bpf_lock_grant\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^FastPathGrantRelationLock$\",\n                \"bpf_lock_fastpath_grant\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^GrantLockLocal$\",\n                \"bpf_lock_local_grant\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^UnGrantLock$\",\n                \"bpf_lock_ungrant\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^FastPathUnGrantRelationLock$\",\n                \"bpf_lock_fastpath_ungrant\",\n                self.args.verbose,\n            )\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^RemoveLocalLock$\",\n                \"bfp_local_lock_ungrant\",\n                self.args.verbose,\n            )\n\n        # Invalidation messages probes\n        if self.args.trace is None or TraceEvents.INVALIDATION.name in self.args.trace:\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^AcceptInvalidationMessages$\",\n                \"bpf_accept_invalidation_messages\",\n                self.args.verbose,\n            )\n\n        # Error probes\n        if self.args.trace is None or TraceEvents.ERROR.name in self.args.trace:\n            BPFHelper.register_ebpf_probe(\n                self.args.path,\n                self.bpf_instance,\n                \"^errstart$\",\n                \"bpf_errstart\",\n                self.args.verbose,\n            )\n\n    def run(self):\n        \"\"\"\n        Run the BPF program and read results\n        \"\"\"\n\n        print(\"===> Ready to trace queries\")\n        while True:\n            try:\n                self.bpf_instance.perf_buffer_poll()\n            except KeyboardInterrupt:\n                if self.output_file:\n                    self.output_file.close()\n\n                if self.args.statistics:\n                    self.output_class.print_statistics()\n                sys.exit(0)\n\n\ndef main():\n    \"\"\"\n    Entry point for the BPF based PostgreSQL lock tracer.\n    \"\"\"\n    args = parser.parse_args()\n\n    pg_lock_tracer = PGLockTracer(args)\n    pg_lock_tracer.init()\n\n    if not args.dry_run:\n        pg_lock_tracer.run()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/pg_lock_tracer/pg_lw_lock_tracer.py",
    "content": "#!/usr/bin/env python3\n#\n# PostgreSQL LW lock tracer. To use this script, PostgreSQL has to be\n# compiled with '--enable-dtrace'.\n#\n# See https://www.postgresql.org/docs/current/dynamic-trace.html\n#\n# List all available USDT probes\n# sudo bpftrace -l \"usdt:/home/jan/postgresql-sandbox/bin/REL_15_1_DEBUG/bin/postgres:*\"\n###############################################\n\nimport sys\nimport argparse\n\nfrom enum import IntEnum, unique\n\nfrom bcc import BPF, USDT\nfrom prettytable import PrettyTable\n\nfrom pg_lock_tracer import __version__\nfrom pg_lock_tracer.helper import BPFHelper\n\nEXAMPLES = \"\"\"examples:\n# Trace the LW locks of the PID 1234\npg_lw_lock_tracer -p 1234\n\n# Trace the LW locks of the PIDs 1234 and 5678\npg_lw_lock_tracer -p 1234 -p 5678\n\n# Trace the LW locks of the PID 1234 and be verbose\npg_lw_lock_tracer -p 1234 -v\n\n# Trace the LW locks of the PID 1234 and collect statistics\npg_lw_lock_tracer -p 1234 -v --statistics\n\"\"\"\n\nparser = argparse.ArgumentParser(\n    description=\"\",\n    formatter_class=argparse.RawDescriptionHelpFormatter,\n    epilog=EXAMPLES,\n)\nparser.add_argument(\n    \"-V\",\n    \"--version\",\n    action=\"version\",\n    version=f\"{parser.prog} ({__version__})\",\n)\nparser.add_argument(\"-v\", \"--verbose\", action=\"store_true\", help=\"Be verbose\")\nparser.add_argument(\n    \"-p\",\n    \"--pid\",\n    type=int,\n    nargs=\"+\",\n    dest=\"pids\",\n    metavar=\"PID\",\n    help=\"the pid(s) to trace\",\n    required=True,\n)\nparser.add_argument(\n    \"-d\",\n    \"--dry-run\",\n    action=\"store_true\",\n    help=\"compile and load the BPF program but exit afterward\",\n)\nparser.add_argument(\"--statistics\", action=\"store_true\", help=\"print lock statistics\")\n\n\n@unique\nclass Events(IntEnum):\n    LOCK = 0\n    LOCK_OR_WAIT = 1\n    LOCK_OR_WAIT_FAIL = 2\n    UNLOCK = 3\n    WAIT_START = 4\n    WAIT_DONE = 5\n    COND_ACQUIRE = 6\n    COND_ACQUIRE_FAIL = 7\n\n\n@unique\nclass LWLockMode(IntEnum):\n    LW_EXCLUSIVE = 0\n    LW_SHARED = 1\n    LW_WAIT_UNTIL_FREE = 2\n\n\nclass LockStatisticsEntry:\n    def __init__(self) -> None:\n        # The number of non-waited requested locks\n        self._direct_lock_count = 0\n\n        # The number of acquire lock or wait calls\n        self._acquire_or_wait_count = 0\n\n        # The number of failed acquire lock or wait calls\n        self._acquire_or_wait_failed_count = 0\n\n        # The number of locks with condition\n        self._lock_cond_count = 0\n\n        # The number of failed lock with condition\n        self._lock_cond_failed_count = 0\n\n        # The number of lock waits\n        self._wait_lock_count = 0\n\n        # The total time spend for lock wait requests\n        self._lock_wait_time_ns = 0\n\n        # A list with the requested locks\n        self._requested_locks = []\n\n    @property\n    def direct_lock_count(self):\n        return self._direct_lock_count\n\n    @direct_lock_count.setter\n    def direct_lock_count(self, value):\n        self._direct_lock_count = value\n\n    @property\n    def acquire_or_wait_count(self):\n        return self._acquire_or_wait_count\n\n    @acquire_or_wait_count.setter\n    def acquire_or_wait_count(self, value):\n        self._acquire_or_wait_count = value\n\n    @property\n    def acquire_or_wait_failed_count(self):\n        return self._acquire_or_wait_failed_count\n\n    @acquire_or_wait_failed_count.setter\n    def acquire_or_wait_failed_count(self, value):\n        self._acquire_or_wait_failed_count = value\n\n    @property\n    def wait_lock_count(self):\n        return self._wait_lock_count\n\n    @wait_lock_count.setter\n    def wait_lock_count(self, value):\n        self._wait_lock_count = value\n\n    @property\n    def lock_cond_count(self):\n        return self._lock_cond_count\n\n    @lock_cond_count.setter\n    def lock_cond_count(self, value):\n        self._lock_cond_count = value\n\n    @property\n    def lock_cond_failed_count(self):\n        return self._lock_cond_failed_count\n\n    @lock_cond_failed_count.setter\n    def lock_cond_failed_count(self, value):\n        self._lock_cond_failed_count = value\n\n    @property\n    def lock_wait_time_ns(self):\n        return self._lock_wait_time_ns\n\n    @lock_wait_time_ns.setter\n    def lock_wait_time_ns(self, value):\n        self._lock_wait_time_ns = value\n\n    @property\n    def requested_locks(self):\n        return self._requested_locks\n\n    @requested_locks.setter\n    def requested_locks(self, lock_type):\n        self._requested_locks.append(lock_type)\n\n\nclass PGLWLockTracer:\n    def __init__(self, prog_args):\n        self.bpf_instance = None\n        self.usdts = None\n        self.prog_args = prog_args\n        self.statistics = {}\n\n        # Variables for lock timing\n        self.last_lock_request_time = {}\n\n    def update_statistics(self, event, tranche, lock_mode):\n        \"\"\"\n        Update the statistics\n        \"\"\"\n\n        if tranche not in self.statistics:\n            self.statistics[tranche] = LockStatisticsEntry()\n\n        statistics_entry = self.statistics.get(tranche)\n\n        # Lock directly requested\n        if event.event_type == Events.LOCK:\n            statistics_entry.direct_lock_count += 1\n            statistics_entry.requested_locks = lock_mode\n            return\n\n        # LWLockAcquireOrWait - Acquired\n        if event.event_type == Events.LOCK_OR_WAIT:\n            statistics_entry.acquire_or_wait_count += 1\n            statistics_entry.requested_locks = lock_mode\n            return\n\n        # LWLockAcquireOrWait - Waited\n        if event.event_type == Events.LOCK_OR_WAIT_FAIL:\n            statistics_entry.acquire_or_wait_failed_count += 1\n            statistics_entry.requested_locks = lock_mode\n            return\n\n        # Wait for lock\n        if event.event_type == Events.WAIT_START:\n            statistics_entry.wait_lock_count += 1\n            self.last_lock_request_time[event.pid] = event.timestamp\n            return\n\n        # Wait for lock done\n        if event.event_type == Events.WAIT_DONE:\n            wait_time = self.get_lock_wait_time(event)\n            statistics_entry.lock_wait_time_ns += wait_time\n            return\n\n        # LWLockConditionalAcquire - Acquire with condition\n        if event.event_type == Events.COND_ACQUIRE:\n            statistics_entry.lock_cond_count += 1\n            statistics_entry.requested_locks = lock_mode\n            return\n\n        # LWLockConditionalAcquire - Condition not possible\n        if event.event_type == Events.COND_ACQUIRE_FAIL:\n            statistics_entry.lock_cond_failed_count += 1\n            statistics_entry.requested_locks = lock_mode\n            return\n\n    def get_lock_wait_time(self, event):\n        \"\"\"\n        Get the last lock wait time (WAIT_START updates\n        last_lock_request_time).\n        \"\"\"\n        if event.event_type != Events.WAIT_DONE:\n            return None\n\n        return event.timestamp - self.last_lock_request_time[event.pid]\n\n    def print_lock_event(self, _cpu, data, _size):\n        \"\"\"\n        Print a new lock event.\n\n        Developer note:\n        Wait events can be tested with second PostgreSQL process and gdb\n        b LWLockAcquireOrWait\n        \"\"\"\n        event = self.bpf_instance[\"lockevents\"].event(data)\n        tranche = event.tranche.decode(\"utf-8\")\n\n        print_prefix = f\"{event.timestamp} [Pid {event.pid}]\"\n        lock_mode = LWLockMode(event.mode).name\n\n        self.update_statistics(event, tranche, lock_mode)\n\n        if event.event_type == Events.LOCK:\n            print(\n                f\"{print_prefix} Acquired lock {tranche} (mode {lock_mode}) / LWLockAcquire()\"\n            )\n        elif event.event_type == Events.LOCK_OR_WAIT:\n            print(\n                f\"{print_prefix} Acquired lock {tranche} (mode {lock_mode}) \"\n                \"/ LWLockConditionalAcquire()\"\n            )\n        elif event.event_type == Events.LOCK_OR_WAIT_FAIL:\n            print(\n                f\"{print_prefix} Waited but not acquired {tranche} (mode {lock_mode}) \"\n                \"/ LWLockConditionalAcquire()\"\n            )\n        elif event.event_type == Events.UNLOCK:\n            print(f\"{print_prefix} Unlock {tranche}\")\n        elif event.event_type == Events.WAIT_START:\n            print(f\"{print_prefix} Wait for {tranche}\")\n        elif event.event_type == Events.WAIT_DONE:\n            lock_time = self.get_lock_wait_time(event)\n            print(f\"{print_prefix} Wait for {tranche} lock took {lock_time} ns\")\n        elif event.event_type == Events.COND_ACQUIRE:\n            print(\n                f\"{print_prefix} Acquired lock {tranche} (mode {lock_mode}) \"\n                \"/ LWLockConditionalAcquire()\"\n            )\n        elif event.event_type == Events.COND_ACQUIRE_FAIL:\n            print(\n                f\"{print_prefix} Failed to acquire lock {tranche} (mode {lock_mode}) \"\n                \"/ LWLockConditionalAcquire()\"\n            )\n        else:\n            raise ValueError(f\"Unknown event type {event.event_type}\")\n\n    def init(self):\n        \"\"\"\n        Compile and load the BPF program\n        \"\"\"\n        print(f\"==> Attaching to PIDs {self.prog_args.pids}\")\n        self.usdts = list(map(lambda pid: USDT(pid=pid), self.prog_args.pids))\n\n        # See https://www.postgresql.org/docs/15/dynamic-trace.html\n        for usdt in self.usdts:\n            usdt.enable_probe(\"lwlock__acquire\", \"lwlock_acquire\")\n            usdt.enable_probe(\"lwlock__acquire__or__wait\", \"lwlock_acquire_or_wait\")\n            usdt.enable_probe(\n                \"lwlock__acquire__or__wait__fail\", \"lwlock_acquire_or_wait_fail\"\n            )\n            usdt.enable_probe(\"lwlock__release\", \"lwlock_release\")\n            usdt.enable_probe(\"lwlock__wait__start\", \"lwlock_wait_start\")\n            usdt.enable_probe(\"lwlock__wait__done\", \"lwlock_wait_done\")\n            usdt.enable_probe(\"lwlock__condacquire\", \"lwlock_condacquire\")\n            usdt.enable_probe(\"lwlock__condacquire__fail\", \"lwlock_condacquire_fail\")\n\n        if self.prog_args.verbose:\n            print(\"=======\")\n            print(\"\\n\".join(map(lambda u: u.get_text(), self.usdts)))\n            print(\"=======\")\n\n        enum_defines = BPFHelper.enum_to_defines(Events, \"EVENT\")\n\n        bpf_program = BPFHelper.read_bpf_program(\"pg_lw_lock_tracer.c\")\n        bpf_program_final = bpf_program.replace(\"__DEFINES__\", enum_defines)\n\n        if self.prog_args.verbose:\n            print(bpf_program_final)\n\n        # Disable warnings like\n        # 'warning: '__HAVE_BUILTIN_BSWAP32__' macro redefined [-Wmacro-redefined]'\n        bpf_cflags = [\"-Wno-macro-redefined\"] if not self.prog_args.verbose else []\n\n        print(\"===> Compiling BPF program\")\n        self.bpf_instance = BPF(\n            text=bpf_program_final, cflags=bpf_cflags, usdt_contexts=self.usdts\n        )\n\n        self.bpf_instance[\"lockevents\"].open_perf_buffer(\n            self.print_lock_event, page_cnt=BPFHelper.page_cnt\n        )\n\n    def print_statistics(self):\n        \"\"\"\n        Print lock statistics\n        \"\"\"\n        print(\"\\nLock statistics:\\n================\")\n\n        # Tranche lock statistics\n        print(\"\\nLocks per tranche\")\n        table = PrettyTable(\n            [\n                \"Tranche\",\n                \"Acquired\",\n                \"AcquireOrWait (Acquired)\",\n                \"AcquireOrWait (Waited)\",\n                \"ConditionalAcquire (Acquired)\",\n                \"ConditionalAcquire (Failed)\",\n                \"Waits\",\n                \"Wait time (ns)\",\n            ]\n        )\n\n        for key in sorted(self.statistics):\n            statistics = self.statistics[key]\n            table.add_row(\n                [\n                    key,\n                    statistics.direct_lock_count,\n                    statistics.acquire_or_wait_count,\n                    statistics.acquire_or_wait_failed_count,\n                    statistics.lock_cond_count,\n                    statistics.lock_cond_failed_count,\n                    statistics.wait_lock_count,\n                    statistics.lock_wait_time_ns,\n                ]\n            )\n\n        print(table)\n\n        # Type lock statistics\n        print(\"\\nLocks per type\")\n        table = PrettyTable([\"Lock type\", \"Requests\"])\n\n        # Map: Key = Lock type, Value = Number of requested locks\n        requested_locks = {}\n\n        for statistics in self.statistics.values():\n            for lock_type in statistics.requested_locks:\n                locks = requested_locks.get(lock_type, 0) + 1\n                requested_locks[lock_type] = locks\n\n        for lock_type in sorted(requested_locks):\n            locks = requested_locks[lock_type]\n            table.add_row([lock_type, locks])\n\n        print(table)\n\n    def run(self):\n        \"\"\"\n        Run the BPF program and read results\n        \"\"\"\n        print(\"===> Ready to trace\")\n        while True:\n            try:\n                self.bpf_instance.perf_buffer_poll()\n            except KeyboardInterrupt:\n                if self.prog_args.statistics:\n                    self.print_statistics()\n                sys.exit(0)\n\n\ndef main():\n    \"\"\"\n    Entry point for the BPF based PostgreSQL LW lock tracer.\n    \"\"\"\n    args = parser.parse_args()\n\n    pg_lock_tracer = PGLWLockTracer(args)\n    pg_lock_tracer.init()\n\n    if not args.dry_run:\n        pg_lock_tracer.run()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/pg_lock_tracer/pg_row_lock_tracer.py",
    "content": "#!/usr/bin/env python3\n#\n# PostgreSQL row lock tracer.\n#\n# See https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS\n#\n###############################################\n\nimport sys\nimport argparse\n\nfrom enum import IntEnum, unique\n\nfrom bcc import BPF\nfrom prettytable import PrettyTable\n\nfrom pg_lock_tracer import __version__\nfrom pg_lock_tracer.helper import BPFHelper\n\nEXAMPLES = \"\"\"examples:\n# Trace the row locks of the given PostgreSQL binary\npg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres\n\n# Trace the row locks of the PID 1234\npg_row_lock_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres\n\n# Trace the row locks of the PID 1234 and 5678\npg_row_lock_tracer -p 1234 -p 5678 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres\n\n# Trace the row locks of the PID 1234 and be verbose\npg_row_lock_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres -v\n\n# Trace the row locks and show statistics\npg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres --statistics\n\"\"\"\n\nparser = argparse.ArgumentParser(\n    description=\"\",\n    formatter_class=argparse.RawDescriptionHelpFormatter,\n    epilog=EXAMPLES,\n)\nparser.add_argument(\n    \"-V\",\n    \"--version\",\n    action=\"version\",\n    version=f\"{parser.prog} ({__version__})\",\n)\nparser.add_argument(\"-v\", \"--verbose\", action=\"store_true\", help=\"Be verbose\")\nparser.add_argument(\n    \"-p\",\n    \"--pid\",\n    type=int,\n    nargs=\"+\",\n    dest=\"pids\",\n    metavar=\"PID\",\n    help=\"the pid(s) to trace\",\n)\nparser.add_argument(\n    \"-x\",\n    \"--exe\",\n    type=str,\n    required=True,\n    dest=\"path\",\n    metavar=\"PATH\",\n    help=\"path to binary\",\n)\nparser.add_argument(\n    \"-d\",\n    \"--dry-run\",\n    action=\"store_true\",\n    help=\"compile and load the BPF program but exit afterward\",\n)\nparser.add_argument(\"--statistics\", action=\"store_true\", help=\"print lock statistics\")\n\n\n@unique\nclass Events(IntEnum):\n    LOCK_TUPLE = 0\n    LOCK_TUPLE_END = 1\n\n\n# See lockoptions.h in PostgreSQL\n@unique\nclass TMResult(IntEnum):\n    TM_OK = 0\n    TM_INVISIBLE = 1\n    TM_SELFMODIFIED = 2\n    TM_UPDATED = 3\n    TM_DELETED = 4\n    TM_BEINGMODIFIED = 5\n    TM_WOULDBLOCK = 6\n\n\n# See lockoptions.h in PostgreSQL\n@unique\nclass LockWaitPolicy(IntEnum):\n    LOCK_WAIT_BLOCK = 0\n    LOCK_WAIT_SKIP = 1\n    LOCK_WAIT_ERROR = 2\n\n\n# See lockoptions.h in PostgreSQL\n@unique\nclass LockTupleMode(IntEnum):\n    LOCK_TUPLE_KEYSHARE = 0\n    LOCK_TUPLE_SHARE = 1\n    LOCK_TUPLE_NOKEYEXCLUSIVE = 2\n    LOCK_TUPLE_EXCLUSIVE = 3\n\n\nclass LockStatisticsEntry:\n    def __init__(self) -> None:\n        # The requested locks\n        self._lock_modes = {}\n\n        # The used lock policies\n        self._lock_policies = {}\n\n        # The lock results\n        self._lock_results = {}\n\n    @property\n    def lock_modes(self):\n        return self._lock_modes\n\n    @lock_modes.setter\n    def lock_modes(self, value):\n        self._lock_modes = value\n\n    @property\n    def lock_policies(self):\n        return self._lock_policies\n\n    @lock_policies.setter\n    def lock_policies(self, value):\n        self._lock_policies = value\n\n    @property\n    def lock_results(self):\n        return self._lock_results\n\n    @lock_results.setter\n    def lock_results(self, value):\n        self._results = value\n\n\nclass PGRowLockTracer:\n    def __init__(self, prog_args):\n        self.bpf_instance = None\n        self.args = prog_args\n        self.statistics = {}\n\n        # Variables for lock timing\n        self.last_lock_request_time = {}\n\n        # Belong the processes to the binary?\n        BPFHelper.check_pid_exe(self.args.pids, self.args.path)\n\n    def get_lock_wait_time(self, event):\n        \"\"\"\n        Get the last lock wait time (WAIT_START updates\n        last_lock_request_time).\n        \"\"\"\n        if event.event_type != Events.LOCK_TUPLE_END:\n            return None\n\n        return event.timestamp - self.last_lock_request_time[event.pid]\n\n    def update_statistics(self, event):\n        \"\"\"\n        Update the statistics\n        \"\"\"\n        if event.pid not in self.statistics:\n            self.statistics[event.pid] = LockStatisticsEntry()\n\n        statistics_entry = self.statistics.get(event.pid)\n\n        # Lock requested\n        if event.event_type == Events.LOCK_TUPLE:\n            lock_wait_policy = LockWaitPolicy(event.lockwaitpolicy)\n\n            if lock_wait_policy in statistics_entry.lock_policies:\n                statistics_entry.lock_policies[lock_wait_policy] += 1\n            else:\n                statistics_entry.lock_policies[lock_wait_policy] = 1\n\n            lock_tuple_mode = LockTupleMode(event.locktuplemode)\n\n            if lock_tuple_mode in statistics_entry.lock_modes:\n                statistics_entry.lock_modes[lock_tuple_mode] += 1\n            else:\n                statistics_entry.lock_modes[lock_tuple_mode] = 1\n\n            return\n\n        # Lock request done\n        if event.event_type == Events.LOCK_TUPLE_END:\n            lock_result = TMResult(event.lockresult)\n\n            if lock_result in statistics_entry.lock_results:\n                statistics_entry.lock_results[lock_result] += 1\n            else:\n                statistics_entry.lock_results[lock_result] = 1\n            return\n\n        return\n\n    def print_lock_event(self, _cpu, data, _size):\n        \"\"\"\n        Print a new lock event.\n        \"\"\"\n        event = self.bpf_instance[\"lockevents\"].event(data)\n\n        if self.args.pids and event.pid not in self.args.pids:\n            return\n\n        print_prefix = f\"{event.timestamp} [Pid {event.pid}]\"\n\n        self.update_statistics(event)\n\n        if event.event_type == Events.LOCK_TUPLE:\n            self.last_lock_request_time[event.pid] = event.timestamp\n\n            locktuplemode = LockTupleMode(event.locktuplemode).name\n            lockwaitpolicy = LockWaitPolicy(event.lockwaitpolicy).name\n\n            print(\n                f\"{print_prefix} LOCK_TUPLE (Tablespace {event.tablespace} \"\n                f\"database {event.database} relation {event.relation}) \"\n                f\"- (Block and offset {event.blockid} {event.offset}) \"\n                f\"- {locktuplemode} {lockwaitpolicy}\"\n            )\n        elif event.event_type == Events.LOCK_TUPLE_END:\n            lockresult = TMResult(event.lockresult).name\n            needed_time = self.get_lock_wait_time(event)\n            print(f\"{print_prefix} LOCK_TUPLE_END {lockresult} in {needed_time} ns\")\n        else:\n            raise ValueError(f\"Unknown event type {event.event_type}\")\n\n    def init(self):\n        \"\"\"\n        Init the PostgreSQL lock tracer\n        \"\"\"\n        enum_defines = BPFHelper.enum_to_defines(Events, \"EVENT\")\n\n        bpf_program = BPFHelper.read_bpf_program(\"pg_row_lock_tracer.c\")\n        bpf_program_final = bpf_program.replace(\"__DEFINES__\", enum_defines)\n\n        if self.args.verbose:\n            print(bpf_program_final)\n\n        # Disable warnings like\n        # 'warning: '__HAVE_BUILTIN_BSWAP32__' macro redefined [-Wmacro-redefined]'\n        bpf_cflags = [\"-Wno-macro-redefined\"] if not self.args.verbose else []\n\n        print(\"===> Compiling BPF program\")\n        self.bpf_instance = BPF(text=bpf_program_final, cflags=bpf_cflags)\n\n        print(\"===> Attaching BPF probes\")\n        self.attach_probes()\n\n        # Open the event queue\n        self.bpf_instance[\"lockevents\"].open_perf_buffer(\n            self.print_lock_event, page_cnt=BPFHelper.page_cnt\n        )\n\n    def attach_probes(self):\n        \"\"\"\n        Attach BPF probes\n        \"\"\"\n        BPFHelper.register_ebpf_probe(\n            self.args.path,\n            self.bpf_instance,\n            \"^heapam_tuple_lock$\",\n            \"heapam_tuple_lock\",\n            self.args.verbose,\n        )\n        BPFHelper.register_ebpf_probe(\n            self.args.path,\n            self.bpf_instance,\n            \"^heapam_tuple_lock$\",\n            \"heapam_tuple_lock_end\",\n            self.args.verbose,\n            False,\n        )\n\n    def print_statistics(self):\n        \"\"\"\n        Print lock statistics\n        \"\"\"\n        print(\"\\nLock statistics:\\n================\")\n\n        # Wait policies\n        print(\"\\nUsed wait policies:\")\n        wait_polices = [\"PID\"]\n\n        for wait_policy in LockWaitPolicy:\n            wait_polices.append(wait_policy.name)\n\n        table = PrettyTable(wait_polices)\n\n        for pid in sorted(self.statistics):\n            statistics = self.statistics[pid]\n            pid_statistics = [pid]\n            for wait_policy in LockWaitPolicy:\n                pid_statistics.append(statistics.lock_policies.get(wait_policy, 0))\n            table.add_row(pid_statistics)\n        print(table)\n\n        # Lock modes\n        print(\"\\nLock modes:\")\n        lock_modes = [\"PID\"]\n\n        for lock_mode in LockTupleMode:\n            lock_modes.append(lock_mode.name)\n\n        table = PrettyTable(lock_modes)\n\n        for pid in sorted(self.statistics):\n            statistics = self.statistics[pid]\n            pid_statistics = [pid]\n            for lock_mode in LockTupleMode:\n                pid_statistics.append(statistics.lock_modes.get(lock_mode, 0))\n            table.add_row(pid_statistics)\n        print(table)\n\n        # Lock results\n        print(\"\\nLock results:\")\n        lock_results = [\"PID\"]\n\n        for lock_result in TMResult:\n            lock_results.append(lock_result.name)\n\n        table = PrettyTable(lock_results)\n\n        for pid in sorted(self.statistics):\n            statistics = self.statistics[pid]\n            pid_statistics = [pid]\n            for lock_result in TMResult:\n                pid_statistics.append(statistics.lock_results.get(lock_result, 0))\n            table.add_row(pid_statistics)\n        print(table)\n\n    def run(self):\n        \"\"\"\n        Run the BPF program and read results\n        \"\"\"\n        print(\"===> Ready to trace\")\n        while True:\n            try:\n                self.bpf_instance.perf_buffer_poll()\n            except KeyboardInterrupt:\n                if self.args.statistics:\n                    self.print_statistics()\n                sys.exit(0)\n\n\ndef main():\n    \"\"\"\n    Entry point for the BPF based PostgreSQL row lock tracer.\n    \"\"\"\n    args = parser.parse_args()\n\n    pg_lock_tracer = PGRowLockTracer(args)\n    pg_lock_tracer.init()\n\n    if not args.dry_run:\n        pg_lock_tracer.run()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/pg_lock_tracer/pg_spinlock_delay_tracer.py",
    "content": "#!/usr/bin/env python3\n#\n# PostgreSQL spinlock delay tracer.\n#\n###############################################\n\nimport sys\nimport argparse\n\nfrom bcc import BPF\n\nfrom pg_lock_tracer import __version__\nfrom pg_lock_tracer.helper import BPFHelper\n\nEXAMPLES = \"\"\"examples:\n# Trace spin delays of the given PostgreSQL binary\npg_spinlock_delay_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres\n\n# Trace spin delays of the PID 1234\npg_spinlock_delay_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres\n\n# Trace spin delays of the PID 1234 and 5678\npg_spinlock_delay_tracer -p 1234 -p 5678 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres\n\n# Trace spin delays of the PID 1234 and be verbose\npg_spinlock_delay_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres -v\n\"\"\"\n\nparser = argparse.ArgumentParser(\n    description=\"\",\n    formatter_class=argparse.RawDescriptionHelpFormatter,\n    epilog=EXAMPLES,\n)\nparser.add_argument(\n    \"-V\",\n    \"--version\",\n    action=\"version\",\n    version=f\"{parser.prog} ({__version__})\",\n)\nparser.add_argument(\"-v\", \"--verbose\", action=\"store_true\", help=\"Be verbose\")\nparser.add_argument(\n    \"-p\",\n    \"--pid\",\n    type=int,\n    nargs=\"+\",\n    dest=\"pids\",\n    metavar=\"PID\",\n    help=\"the pid(s) to trace\",\n)\nparser.add_argument(\n    \"-x\",\n    \"--exe\",\n    type=str,\n    required=True,\n    dest=\"path\",\n    metavar=\"PATH\",\n    help=\"path to binary\",\n)\nparser.add_argument(\n    \"-d\",\n    \"--dry-run\",\n    action=\"store_true\",\n    help=\"compile and load the BPF program but exit afterward\",\n)\n\n\nclass PGSpinDelayTracer:\n    def __init__(self, prog_args):\n        self.bpf_instance = None\n        self.args = prog_args\n\n        # Belong the processes to the binary?\n        BPFHelper.check_pid_exe(self.args.pids, self.args.path)\n\n    @staticmethod\n    def _decode_field(value):\n        return value.decode(\"utf-8\", \"replace\").rstrip(\"\\x00\")\n\n    def print_lock_event(self, _cpu, data, _size):\n        \"\"\"\n        Print a new spin delay event.\n        \"\"\"\n        event = self.bpf_instance[\"lockevents\"].event(data)\n\n        if self.args.pids and event.pid not in self.args.pids:\n            return\n\n        file_name = self._decode_field(event.file) or \"(unknown)\"\n        func_name = self._decode_field(event.func) or \"(unknown)\"\n\n        print(\n            f\"{event.timestamp} [Pid {event.pid}] SpinDelay \"\n            f\"spins={event.spins} delays={event.delays} \"\n            f\"cur_delay={event.cur_delay} at {func_name}, {file_name}:{event.line}\"\n        )\n\n    def init(self):\n        \"\"\"\n        Init the PostgreSQL spin delay tracer\n        \"\"\"\n        bpf_program = BPFHelper.read_bpf_program(\"pg_spinlock_delay_tracer.c\")\n\n        if self.args.verbose:\n            print(bpf_program)\n\n        # Disable warnings like\n        # 'warning: '__HAVE_BUILTIN_BSWAP32__' macro redefined [-Wmacro-redefined]'\n        bpf_cflags = [\"-Wno-macro-redefined\"] if not self.args.verbose else []\n\n        print(\"===> Compiling BPF program\")\n        self.bpf_instance = BPF(text=bpf_program, cflags=bpf_cflags)\n\n        print(\"===> Attaching BPF probes\")\n        self.attach_probes()\n\n        # Open the event queue\n        self.bpf_instance[\"lockevents\"].open_perf_buffer(\n            self.print_lock_event, page_cnt=BPFHelper.page_cnt\n        )\n\n    def attach_probes(self):\n        \"\"\"\n        Attach BPF probes\n        \"\"\"\n        BPFHelper.register_ebpf_probe(\n            self.args.path,\n            self.bpf_instance,\n            \"^perform_spin_delay$\",\n            \"spin_delay\",\n            self.args.verbose,\n        )\n\n    def run(self):\n        \"\"\"\n        Run the BPF program and read results\n        \"\"\"\n        print(\"===> Ready to trace\")\n        while True:\n            try:\n                self.bpf_instance.perf_buffer_poll()\n            except KeyboardInterrupt:\n                sys.exit(0)\n\n\ndef main():\n    \"\"\"\n    Entry point for the BPF based PostgreSQL spin delay tracer.\n    \"\"\"\n    args = parser.parse_args()\n\n    pg_spin_delay_tracer = PGSpinDelayTracer(args)\n    pg_spin_delay_tracer.init()\n\n    if not args.dry_run:\n        pg_spin_delay_tracer.run()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "tests/__init__.py",
    "content": ""
  },
  {
    "path": "tests/test_helper.py",
    "content": "#!/usr/bin/env python3\n\nimport unittest\n\nfrom src.pg_lock_tracer.helper import PostgreSQLLockHelper\n\n\nclass UNITTests(unittest.TestCase):\n    def test_encode_locks(self):\n        \"\"\"\n        Test the encoding of locks\n        \"\"\"\n        my_locks = [\n            \"NoLock\",\n            \"AccessShareLock\",\n            \"ShareRowExclusiveLock\",\n            \"AccessExclusiveLock\",\n        ]\n\n        my_locks_numeric = list(map(PostgreSQLLockHelper.lock_type_to_int, my_locks))\n\n        # Test conversion was ok\n        self.assertListEqual([0, 1, 6, 8], my_locks_numeric)\n\n    def encode_and_decode_locks(self, locks):\n        \"\"\"\n        Decode and encode the list of locks and test for errors\n        \"\"\"\n\n        # Convert into numeric values\n        my_locks_numeric = list(map(PostgreSQLLockHelper.lock_type_to_int, locks))\n\n        # Encode and decode into single value\n        single_value = PostgreSQLLockHelper.encode_locks_into_value(my_locks_numeric)\n        decoded_locks = PostgreSQLLockHelper.decode_locks_from_value(single_value)\n\n        decoded_my_locks = list(\n            map(PostgreSQLLockHelper.lock_type_to_str, decoded_locks)\n        )\n        self.assertListEqual(locks, decoded_my_locks)\n\n    def test_parse_lock_decoding_and_encoding0(self):\n        \"\"\"\n        Test encoding and decoding of locks into a single value\n        \"\"\"\n\n        my_locks = [\n            \"AccessExclusiveLock\",\n        ]\n\n        self.encode_and_decode_locks(my_locks)\n\n    def test_parse_lock_decoding_and_encoding1(self):\n        \"\"\"\n        Test encoding and decoding of locks into a single value\n        \"\"\"\n\n        my_locks = [\n            \"NoLock\",\n            \"AccessShareLock\",\n            \"ShareRowExclusiveLock\",\n            \"AccessExclusiveLock\",\n        ]\n\n        self.encode_and_decode_locks(my_locks)\n\n    def test_parse_lock_decoding_and_encoding2(self):\n        \"\"\"\n        Test encoding and decoding of locks into a single value\n        \"\"\"\n\n        my_locks = [\"NoLock\"]\n\n        self.encode_and_decode_locks(my_locks)\n\n    def test_parse_lock_decoding_and_encoding3(self):\n        \"\"\"\n        Test encoding and decoding of locks into a single value\n        \"\"\"\n\n        my_locks = []\n\n        self.encode_and_decode_locks(my_locks)\n\n    def test_parse_lock_decoding_and_encoding_dup(self):\n        \"\"\"\n        Test encoding and decoding with duplicates\n        \"\"\"\n\n        my_locks = [\n            \"AccessShareLock\",\n            \"AccessShareLock\",\n            \"AccessShareLock\",\n            \"ShareRowExclusiveLock\",\n            \"ShareRowExclusiveLock\",\n        ]\n\n        my_locks_numeric = list(map(PostgreSQLLockHelper.lock_type_to_int, my_locks))\n\n        # Encode and decode into single value\n        single_value = PostgreSQLLockHelper.encode_locks_into_value(my_locks_numeric)\n        decoded_locks = PostgreSQLLockHelper.decode_locks_from_value(single_value)\n\n        decoded_my_locks = list(\n            map(PostgreSQLLockHelper.lock_type_to_str, decoded_locks)\n        )\n\n        # Only unique values are present\n        self.assertListEqual([my_locks[0], my_locks[4]], decoded_my_locks)\n"
  }
]