Вести с полей. День проблем с серверами

Привет всем.

Сегодня интересный день. День багов. Все началось с того, что я решил обновить основной тестовый сервер до FB2.5.1.26182. На нем перестал отрабатывать один из служебных запросов провайдера.

Выглядит этот запрос так:

select pk_c.rdb$relation_name as pk_table_name,
       iseg_pk.rdb$field_name as pk_field_name,
       fk_c.rdb$relation_name as fk_table_name,
       iseg_fk.rdb$field_name as fk_field_name,
       rc.rdb$const_name_uq as pk_name,
       rc.rdb$constraint_name as fk_name,
       rc.rdb$update_rule as update_rule,
       rc.rdb$delete_rule as delete_rule,
       iseg_fk.rdb$field_position as field_position
from rdb$index_segments iseg_pk
       join rdb$relation_constraints pk_c
        join rdb$ref_constraints rc
         join rdb$relation_constraints fk_c
          join rdb$index_segments iseg_fk
          on fk_c.rdb$index_name=iseg_fk.rdb$index_name and
             iseg_fk.rdb$field_position=iseg_pk.rdb$field_position
         on rc.rdb$constraint_name=fk_c.rdb$constraint_name
        on pk_c.rdb$constraint_name=rc.rdb$const_name_uq
       on iseg_pk.rdb$index_name = pk_c.rdb$index_name

Сервер возвращает ошибку

Dynamic SQL Error.
SQL error code = -206.
Column unknown.
ISEG_PK.RDB$FIELD_POSITION.
At line 16, column 49.

После непродолжительной консультации по этой теме, было принято решение на всякий случай переделать сам запрос, а не ждать исправления в сервере. Если такое вообще будет.

Решив проблему с FB, подумалось об IB — с ним там вообще как? Все в порядке?

Для получения ответа на этот риторический вопрос был запущен тест schema.002.read_schema.schema_cache_0. Это адский тест, который перебирает все возможные комбинации получения схем метаданных при выключенном кэше. Адский, потому что было время, когда он работал больше суток. Сейчас, после многочисленных оптимизаций в провайдере — где-то в районе 3.5 часов.

Сервер — IB10. Получили такие ошибки:

[23.01.2011 18:49:52] ERROR: [read_schema] Schema DBSCHEMA_CONSTRAINT_COLUMN_USAGE [{C8B52216-5CF3-11CE-ADE5-00AA0044773D}]
GetSchema return BAD rowset with 0 records for this restrictions:
«CONSTRAINT_NAME»=bstr»CHECK_DUAL»

[23.01.2011 19:02:21] ERROR: [read_schema] Schema DBSCHEMA_CONSTRAINT_TABLE_USAGE [{C8B52217-5CF3-11CE-ADE5-00AA0044773D}]
GetSchema return BAD rowset with 0 records for this restrictions:
«CONSTRAINT_NAME»=bstr»CHECK_DUAL»

[23.01.2011 19:13:30] ERROR: [read_schema] Schema DBSCHEMA_COLUMN_PRIVILEGES [{C8B52221-5CF3-11CE-ADE5-00AA0044773D}]
GetSchema return BAD rowset with 0 records for this restrictions:
«COLUMN_NAME»=bstr»CHAR_OCTETS»

Ага. Давайте рассмотрим поближе первую ошибку. Для этого был создан изолированный тест на VBS

option explicit

dim cn

set cn=createobject("ADODB.Connection")

cn.Provider="LCPI.IBProvider"

cn.Properties("location")         ="vxpsp2-ib100:e:\database\ibp_test_ib100_d3.gdb"
cn.Properties("user id")          ="gamer"
cn.Properties("password")         ="vermut"
cn.Properties("ctype")            ="win1251"
cn.Properties("dbclient_library") ="d:\Users\Dima\IB_FB_YA\IB100\gds32.dll"
cn.Properties("stmt_cache__time") =0

call cn.Open()

wscript.echo "DBMS Name   :"&cstr_sn(cn.properties("DBMS Name").value)
wscript.echo "DBMS Version:"&cstr_sn(cn.properties("DBMS Version").value)
wscript.echo ""

call cn.BeginTrans()

test_1(cn)
test_2(cn)

call wscript.quit(0)

'+++++++++++++++++++++++++++++++++++++++++++
sub test_1(cn)
 wscript.echo "------------------ TEST 1"
 
 dim cmd
 set cmd=create_cmd(cn)

 call run_cmd(cmd,"INTEG_3")

 set cmd=create_cmd(cn)

 call run_cmd(cmd,"CHECK_DUAL")
end sub' test_1

'+++++++++++++++++++++++++++++++++++++++++++
sub test_2(cn)
 wscript.echo "------------------ TEST 2"
 
 dim cmd
 set cmd=create_cmd(cn)

 call run_cmd(cmd,"INTEG_3")

 'set cmd=create_cmd(cn)

 call run_cmd(cmd,"CHECK_DUAL")
end sub' test_2

'+++++++++++++++++++++++++++++++++++++++++++
private function create_cmd(cn)
 dim cmd
 
 set cmd=createobject("ADODB.Command")
 cmd.ActiveConnection=cn

 cmd.CommandText= _
  "select rc1.rdb$constraint_name," & vbCrLf & _
  "rc1.rdb$relation_name," & vbCrLf & _
  "iseg1.rdb$field_name," & vbCrLf & _
  "rc1.rdb$constraint_type" & vbCrLf & _
  "from rdb$relation_constraints rc1" & vbCrLf & _
  "join rdb$index_segments iseg1" & vbCrLf & _
  "on rc1.rdb$index_name=iseg1.rdb$index_name" & vbCrLf & _
  "where rc1.rdb$constraint_name=:a" & vbCrLf & _
  "union" & vbCrLf & _
  "select rc2.rdb$constraint_name," & vbCrLf & _
  "dep2.rdb$depended_on_name," & vbCrLf & _
  "dep2.rdb$field_name," & vbCrLf & _
  "rc2.rdb$constraint_type" & vbCrLf & _
  "from rdb$relation_constraints rc2" & vbCrLf & _
  "join rdb$check_constraints cc2" & vbCrLf & _
  "join rdb$dependencies dep2" & vbCrLf & _
  "on dep2.rdb$dependent_name=cc2.rdb$trigger_name and" & vbCrLf & _
  "dep2.rdb$dependent_type=2 and" & vbCrLf & _
  "((dep2.rdb$depended_on_type is NULL) or" & vbCrLf & _
  "(dep2.rdb$depended_on_type in (0,1))) and" & vbCrLf & _
  "(dep2.rdb$field_name is not null) and" & vbCrLf & _
  "(dep2.rdb$field_name<>'')" & vbCrLf & _
  "on (rc2.rdb$constraint_name=cc2.rdb$constraint_name and" & vbCrLf & _
  "rc2.rdb$constraint_type='CHECK')" & vbCrLf & _
  "where rc2.rdb$constraint_name=:a" & vbCrLf & _
  "union" & vbCrLf & _
  "select rc3_fk.rdb$constraint_name," & vbCrLf & _
  "rc3_pk.rdb$relation_name," & vbCrLf & _
  "iseg3_pk.rdb$field_name," & vbCrLf & _
  "rc3_fk.rdb$constraint_type" & vbCrLf & _
  "from rdb$relation_constraints rc3_fk" & vbCrLf & _
  "join rdb$ref_constraints ref_c3" & vbCrLf & _
  "join rdb$relation_constraints rc3_pk" & vbCrLf & _
  "join rdb$index_segments iseg3_pk" & vbCrLf & _
  "on rc3_pk.rdb$index_name=iseg3_pk.rdb$index_name" & vbCrLf & _
  "on ref_c3.rdb$const_name_uq=rc3_pk.rdb$constraint_name" & vbCrLf & _
  "on rc3_fk.rdb$constraint_name=ref_c3.rdb$constraint_name" & vbCrLf & _
  "where rc3_fk.rdb$constraint_name=:a"

 set create_cmd=cmd
end function 'create_cmd

'+++++++++++++++++++++++++++++++++++++++++++
private sub run_cmd(cmd,param)
 wscript.echo ""
 wscript.echo "param:"&param

 cmd("a")=param

 dim rs

 set rs=cmd.execute()

 while(not rs.eof)
  wscript.echo cstr_sn(rs(0).value)

  call rs.movenext()
 wend
end sub 'run_cmd

'+++++++++++++++++++++++++++++++++++++++++++
Function cstr_sn(s)
  If (IsNull(s)) Then
    cstr_sn = "#NULL"
  Else
    cstr_sn = CStr(s)
  End If
End Function ' su_cstr_sn_ex

'+++++++++++++++++++++++++++++++++++++++++++

Вывод

DBMS Name :InterBase
DBMS Version:10.0.0.247
—————— TEST 1
param:INTEG_3
INTEG_3
param:CHECK_DUAL
CHECK_DUAL
—————— TEST 2
param:INTEG_3
INTEG_3
param:CHECK_DUAL

Первый тест пересоздает запрос. Второй тест — дважды вызывает один и тот же запрос с разными параметрами. Результаты работы тестов должны быть идентичными. Однако во втором тесте, когда запрос выполняется второй раз, мы получаем пустое множество.

А что по этому поводу нам скажет IB7.5?

DBMS Name :InterBase
DBMS Version:7.5.1.80
—————— TEST 1
param:INTEG_3
INTEG_3
param:CHECK_DUAL
CHECK_DUAL
—————— TEST 2
param:INTEG_3
INTEG_3
param:CHECK_DUAL
CHECK_DUAL

Он (InterBase 7.5.1) говорит, что все путём. Оба теста возвращают идентичные результаты. Даже если разрешить пул запросов (закомментировать установку свойства stmt_cache__time) — результат будет тот же. То есть правильный.

Вот такие вот дела.

2 комментария

Interbase 2010  on 24 января, 2011

Interbase пошел по наклонной?

Kovalenko  on 10 августа, 2011

Они её пофиксили в сборке 10.0.2.474

Leave a Comment