【问题标题】:How is it possible for this Python query to alternate between two different results?这个 Python 查询如何在两个不同的结果之间交替?
【发布时间】:2022-01-11 20:08:18
【问题描述】:

我正在执行以下代码,

import psycopg2
import pandas as pd

@contextmanager
def get_psyopg2_connection(server='my_server', port=1234, read_only=True):
    try:
        conn = psycopg2.connect("<connection_string>")
        conn.set_session(readonly=read_only, autocommit=True)
        yield conn
    except Exception as e:
        raise Exception(e) from e
    finally:
        conn.close()

if __name__=="__main__":

    with get_psyopg2_connection() as conn_dev:

        df = pd.read_sql("""select last_value from public.lime_boxes_id_seq""", conn_dev)
        print(df)

我收到两个不同的结果; last_value = 6(正确)和 33(错误)。当我多次运行相同的代码时,我可能会得到像 6、6、6、33、33、6 这样的结果序列。这是不可预测的。

当我在 DBeaver 中执行此查询时,我总是得到 6。

怎么会这样?

编辑:

这个表是一个序列,除了我自己没有人访问这个模式。这是内容

last_value log_cnt is_called
6 27 true

【问题讨论】:

  • 您能否将public.lime_boxes_id_seq 表格中的内容样本作为问题正文中的文本格式表格分享? 33 实际上是包含在表中某行的last_value 属性中的值吗?您能否分享一下您遵循的逻辑,即6 是在这种情况下应该返回的“正确”值?您没有指定任何ORDER BY 子句;因此无法保证返回记录的顺序(请参阅this thread)。
  • 有没有可能my_server 实际上是 Postgres 集群的负载均衡器,它没有在节点之间正确复制,因此每次重新连接时都会为同一查询返回不同的结果运行这个脚本?它将完全解释您的 DBeaver 客户端每次获得相同结果的原因(它可能不是在查询之间连接/断开/重新连接,可能每次都连接到不同的服务器,并且可能在查询之间保持相同的连接),但是您的代码(连接/断开/重新连接每次执行)不会。
  • 有问题的值是否曾经33?如果是这样,您的代码和返回此错误数据的数据库服务器之间是否可能存在某种缓存机制?如果它被缓存并且从未释放,这也可能是该数据没有返回您认为应该返回的内容的原因,并且缓存刷新/重新配置是必要的。
  • @esqew 是的,my_server 是用于开发工作的负载均衡器。
  • 如果情况确实如此(我必须承认有点幸运的猜测),我建议验证负载平衡设备/配置背后的每个节点的完整性,以确保数据在节点之间匹配.对我来说,这听起来像是一个或多个集群节点之间的复制问题,您的负载均衡器在某些会话上将您连接到这些节点,但不是全部。

标签: python postgresql psycopg2


【解决方案1】:

我认为有 3 种不同的可能性:

  1. public.lime_boxes_id_seq中有多条记录,由于您没有指定ORDER BY子句,数据库将不保证记录返回的顺序。虽然这绝对是一个低可能性,但仍然值得探索被查询的表实际包含哪些数据并从那里开始工作。

  2. 有问题的数据库服务器 (my_server) 实际上是某种负载平衡器,用于其后面的 Postgres 节点集群,并且有一个或多个节点与其余节点不同步,并且返回旧的/不正确的数据。 这将完全解释您的 DBeaver 客户端每次获得相同结果的原因(它可能不是在查询之间连接/断开/重新连接,可能每次都连接到不同的服务器,并且可能在它们之间保持相同的连接查询),但您的代码(连接/断开/重新连接每次执行)没有。为了缓解这种情况,您可以连接到集群中已知良好的节点(如果您的网络设置允许这样的安排),或者修复导致数据过时的复制问题。

  3. 如果有问题的值曾经是 33,则可能在您的代码和 Postgres 中返回错误数据的表之间的网络中存在某种缓存机制。 如果是已被此设备/这些设备缓存并且从那时起未刷新,这也可能是此数据未返回您认为应该返回的内容的原因,并且缓存刷新/重新配置是必要的。

【讨论】:

  • 谢谢@esqew! #2。解决了这个问题。 my_server 是一个负载均衡器,我刚刚测试了连接到它使用的两个单独的服务器。一个的结果是 6,另一个是 33。
猜你喜欢
  • 1970-01-01
  • 2017-07-19
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-02
相关资源
最近更新 更多