Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Проблемма с индексом / 7 сообщений из 7, страница 1 из 1
15.09.2006, 08:55
    #33989083
Jura.K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемма с индексом
Столкнулся с такой проблеммой
периодически падают индексы, но падают они как то интересно.
Запись в таблице имеется, а вот ссылка в индексе на эту запись пропадает,
при этом некоторое время назад она была.
Если бы при падении индекса была выдана хотя бы ошибка, то можно было бы своевременно произвести переиндексацию данных, а так получается что и не знаешь в какой момент этот индекс корректный, а в какой нет.
Узнать что индекс некорректный можно только при поиске с использованием SEEK, записи которая должна входить в этот индекс - если не найдена значит индекс некорректный, делаем переиндексацию и после этого запись находится.
Заметил что чаще падают индексы в которые включены поля размером более 25 символов, ну и конечно составные.

Может кто подскажет как отловить момент падения этого индекса.
VFP 8.0 +SP1, используется транзакция но не длинная, а на момент выполнения TABLEUPDATE() в ходе которой идет обновление где-то в среднем по 4 таблицам.
...
Рейтинг: 0 / 0
15.09.2006, 09:24
    #33989149
PaulWist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемма с индексом
Давай код транзакции.
...
Рейтинг: 0 / 0
15.09.2006, 09:58
    #33989235
Jura.K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемма с индексом
код я скинул на Ваш e-mail
т.к. он большой и места занимет много,
но кажется проблемма не в нем.
Если все же нужно повторить то я повторю в форуме
...
Рейтинг: 0 / 0
15.09.2006, 10:29
    #33989333
PaulWist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемма с индексом
Мда, немного мутновато.

Мне не понятны телодвижени внутри транзакции, почему нельзя сначала провести все необходимые scan, seek снаружи транзакции и только в последний момент написать

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
BEGIN TRAN
* вот здесь сказать TableUpdate() всем алиасам
            m.llUpdate = TableUpdate()
            .....
	IF m.llUpdate
		END TRANSACTION 
		this.llUpdateRecord=.T. 
	ELSE 
		=AERROR(aErrorArray)
		ROLLBACK 

* Ну и вот здесь бы надо поменять местами
		this.llUpdateRecord=.F. 

* А вот эти откаты на мой взгляд вообще не нужны, те если у тебя происходит 
* ошибка обновления (ну там ограничение сработало на внешний ключ) то,
* что ты делаешь, а просто весь пользовательский ввод откатываешь и юзеру 
* всё надо начинать сначала.
		TABLEREVERT(.T.,"T11")
		TABLEREVERT(.T.,"T11D")
		TABLEREVERT(.T.,"T11L")
	ENDIF 		
...
Рейтинг: 0 / 0
15.09.2006, 12:52
    #33989968
Jura.K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемма с индексом
Раньше примерно так и было,но тогда была оптимистическая блокировка всех таблиц.
Стал искать причину думал из-за опимистической блокировки таблиц.
Сделал основные таблицы с оптимистической блокировкой строк. Поэтому и получилось так,
что для всех таблиц (подчиненных) имеющих оптимистическую блокировку таблиц, делается
TABLEUPDATE() , потом идет Seek и Sacn, а также Replace
для нескольких записей основной таблицы.
Сответственно после каждого Replace основной таблицы делаем следующую проверочку
IF !TABLEUPDATE(0,.F.,"T11")
m.llUpdate=.F.
ENDIF
Вот поэтому такой код и получился.

BEGIN TRANSACTION
IF !TABLEUPDATE(0,.F.,"T11D")
llUpdate=.F.
ENDIF
IF !TABLEUPDATE(1,.F.,"T11L")
llUpdate=.F.
ENDIF
IF !TABLEUPDATE(0,.F.,"T11")
llUpdate=.F.
ENDIF
*!* здесь мы сказали Tableupdate() только 3 таблицам
..........
SCAN WHILE F11IDPAR=m.lcF11IDPar
REPLACE F11Status WITH IIF(F11Status='1','2','4')
IF !TABLEUPDATE(0,.F.,"T11")
llUpdate=.F.
ENDIF
ENDSCAN
*!* здесь мы говорим Tableupdate() для каждой измененной записи основной таблицы
...... подобный код повторяется но он немного другой

GO m.lnRecnoEof
REPLACE F11F30EOF WITH .T.
IF !TABLEUPDATE(1,.F.,"T11")
llUpdate=.F.
ENDIF
*!* здесь мы говорим Tableupdate() для каждой измененной записи основной таблицы
....... опять повторение подобного кода при других условиях и для других записей

*!* теперь проверяем для не было ли ошибки при выполнение Tableupdate() хотя бы для одной таблицы
IF m.llUpdate
END TRANSACTION
this.llUpdateRecord=.T. && Ни чего здесь местами менять не нужно это свойство я потом анализирую
lcResult='1 Данные сохранены!!!'
ELSE
this.llUpdateRecord=.F.
=AERROR(aErrorArray)
ROLLBACK
TABLEREVERT(.T.,"T11")
TABLEREVERT(.T.,"T11D")
TABLEREVERT(.T.,"T11L")
lcResult='0 В ходе сохранения данных возникла ошибка:'+CHR(13)+ ;
aErrorArray(1,2)+CHR(13)+ 'Данные потеряны'
ENDIF
RETURN m.lcResult

Вот поэтому и получился такой код из-за того, что я почему то подумал что причина кроется в
оптимистической буфферизации таблицы. Раньше был такой как и Вы предлагаете, но все равно индексы падали.
А по поводу "откатываешь весь код и юзеру все начинать сначала"
Да именно так, такая ошибка за 2 года эксплуатации возникла только один раз,
там так сказать администратор грамотный попался, он таблицу хранения идентификаторов
(она хранит последний запрошенный идентификатор), вытащил из архива и
при этом только одну и решил ее поменять. Соответственно сгенерился уже имеющийся идентификатор.
Так что показывать пользователю и говорить что не могу сохранить потому что возникла ошибка
уникализации, ни к чему не приведет. (Пользователь еще перезагрузит компьютер,
а это они любят делать.) Так что будем получать идентификатор заново вводить повтрно данные, т.к.
ссылка на этот идентификатор идет из других полей и других таблиц.

PS.
Индексы падают не постоянно, а изредка. И причина не в транзакциях,
а скорее всего в не совсем качественных сетях, которые имеют место быть.
(программа стоит не в одном месте, а достаточно распространена).
Поэтому я и спрашиваю может кто знает как узнать что индекс не соответсвует таблице,
при этом он такой ошибки не дает .
Я понимаю что лучше было бы использовать вьюшки, но код написан и переделывать очень много.
Позже буду переделывать уже хранилище на MySQL там и изменю.
...
Рейтинг: 0 / 0
15.09.2006, 13:11
    #33990050
PaulWist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемма с индексом
Как правило индексы летят из-за железа - это факт.

Теперь по поводу вот этой конструкции

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
IF !TABLEUPDATE( 0 ,.F.,"T11D") 
llUpdate=.F.
ENDIF 
IF !TABLEUPDATE( 1 ,.F.,"T11L")
llUpdate=.F.
ENDIF 
IF !TABLEUPDATE( 0 ,.F.,"T11")
llUpdate=.F.
ENDIF

те в принципе если на первой проверке получим .F., то все остальные действия бессмыслены, всё равно придется откатывать транзакцию, ну и так далее по тексту.

Узнать побит ли индекс можно только сопоставив записи в таблице с записями в индексе, те фактически выполнив переиндексацию.
...
Рейтинг: 0 / 0
15.09.2006, 13:40
    #33990169
Jura.K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемма с индексом
Ну согласен можно было и так
Код: plaintext
1.
2.
3.
4.
5.
LOCAL llUpdate
m.llUpdate=.F.
IF TABLEUPDATE( 0 ,.F.,"T11D") AND TABLEUPDATE( 1 ,.F.,"T11L") AND TABLEUPDATE( 0 ,.F.,"T11")
      *!* здесь дальнейший код
ENDIF 

PaulWistКак правило индексы летят из-за железа - это факт.
Значит железо...понятно :-(
PaulWistУзнать побит ли индекс можно только сопоставив записи в таблице с записями в индексе, те фактически выполнив переиндексацию.
значит другого выхода нет
к сожалению таблицы по объему не маленькие делать переиндексацию при старте программы не получается, да и работа ведется по сети
Остается дать команду настроить планировщик задачь на переиндексацию на ночь. Хотя не факт что ночью компьютер будет работать
Спасибо за ответ и совет !!!
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Проблемма с индексом / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]