Ett forum jag har (asp och access) går ej längre att uppdatera på något sätt. När jag försöker uppdatera eller radera databasen via ftp så får jag ett meddelande att jag har ingen åtkomst till filen, den är låsta av en annan process. Det finns även en .ldb fil i katalogen. Dessutom har filen vuxit enormt från ca 4 Mb till 2Gb. Vad gör jag för att lösa detta och undvika att det händer igen? Låter som att en tråd har fastad i en loop och hela tiden insertar mer information, därav storleken samt låsningen av filen. Du får nog konaktra isp:n och be dem döda din process. Sen titta överkoden! Låter som jag får låta isp:n fixa det, men jag har använt samma kod i två år utan problem tidigare. Skumt... Det där är ett vanligt missförstånd.. "jag har ju använt den länge så då är den rätt". Det är en slutsats som är helt felaktigt att dra. Det enda som man kan se är att fram till nu så har man lyckats undvika det scenario som ger denna bugg. Problemet kvarstår forfarande. Det har ju varit helg så min ISP har väl inte noterat problemet. Jag har dock kunnat tanka hem en kopia på databasen för att kolla lite. Det har inte lagrats några onormala mängder data. Data sparas från ett formulär med en enkel insert-sats. Trots detta så växer storleken på databasen kraftigt. Detta fenomen har funnits tidigare. Om man kör en "reparera och komprimera" så sjunker storleken till normala 4Mb. Jag kan inte hitta någon begränsning i antalet poster, däremot finns det en gräns på 2GB på mdb-filen (det var nog den du råkade ut för?). Någon log-fil för Access har jag aldrig hört talas om, kanske är någon som har förväxlat det med transaktionsloggen i SQL Server eller någon annan databashanterare? Hummm, detta verkar märkligt. All data hanteras i "hidden fields" i formulär till den ska sparas i databasen. Inga temporära tabeller eller liknande. Databasen växer alltså från 4 MB till 2 GB utan att mängden data i tabellerna ökar. Det låter som jag får kontakta webbhotellet och kolla läget lite. Hur ser koden ut som "pratar" med databasen? Du skapar inga poster som du sedan aldrig sparar t.ex? Jag måste nog sätta mig in i koden lite mer. Jag har bara modifierat en befintlig kod som jag inte har skrivit själv. Det jag har svårt för att greppa är hur databasen kan växa så otroligt när det inte sparas någon data i den. Vad är det då som "tar plats"? Att filen växer beror oftast på att man modifierar innehållet, redigerar och tar bort poster. När en post tas bort får man inte tillbaka utrymmet, då hade man behövt stuva om hela filen för att få allt i rätt ordning och det är prestandakrävande. Precis som en hårddisk som blir fragmenterad. Därför måste man manuellt starta processen som tar bort allt tomutrymme i databasfilen. Jag har i.o.f.s. runt 10000 besök per månad som ger en hel del visningar från databasen. Får väl inrikta mig på om det är något där bygger upp allt skräp till att börja med. Tack för hjälpen så länge. Eftersom jag nu siktar på att det kan vara något fel på koden som visar/sparar inläggen så postar jag den här. Det blir kanske lite fel med asp-kod här i Accessforumet men... Det blir mycket kod men jag hoppas ni kan sortera ut det väsentliga. Vid varje läsning uppdateras ReadCount, jag vet inte hur Access hanterar det, men det skulle kunna vara detta som får filen att växa... Man tycker ju att en ändring av ett fält med fast längd inte borde fragmentera databasen, men jag vet som sagt inte hur detta hanteras, en gissning alltså. Om du har möjlighet kan du ju testa att kommentera bort uppdateringen och se om det blir någon skilllnad. Funderade faktiskt på samma sak innan jag slocknade på bussen på väg hem från jobbet ;) Jag har kommenterat bort uppdateringen så får vi se i mogon bitti om den har växt till sig. Mycket riktigt så var det uppdateringen av ett fält vid varje visning som fick databasen att svälla. Grundproblemet är väl löst så jag tackar för hjälpen och markerar tråden som löst. Är det däremot någon som kan svara på varför storleken på databasen ökar med ca 1Kb bara för att man ökar värdet i en post med 1 så är ni välkommna. Lägger man in en helt ny post med ett tiotal fält så händer nästan ingenting med storleken på databasen. Det känns lite som om du har ett index på den kolumnen och att det är en massa index som byggs om. Men eftersom filen inte skriver över så växer den och lämnar en massa tomt utrymme efter sig. Typ. Jag är ingen fena på Access men när jag kollar i "design view" så är det inget index på den kolumnen som uppdateras vid läsning. Däremot står det "indexerat" på ParentMessage samt "ID". Följande fält finns i databasen: Hej Peter,Databasen låst av en annan process
Sv: Databasen låst av en annan process
Sv:Databasen låst av en annan process
Sv: Databasen låst av en annan process
Således, kolla koden, men kolla även den data som lagrats för att kunna dra slutsatser om vad som går snett så att du kan rätta till det.
// Johan
PS. Microsoft har släppt windows XP för flera år sedan och anser inte att bara för att den är gammal att den är bra..man släpper fortfarande rättningar till Windows och lär göra så länge till.Sv:Databasen låst av en annan process
Jag har därför (med ett script från pellesoft) kört detta manuellt på servern med ojämna mellanrum. Men varför växer databasen så fort trots att det bara är knappt 10 000 poster och den ökar med ca 20-50 poster/dygn? Någon nämnde något om en loggfil i Access som man kan begränsa storleken på men jag hittar inget om detta. Finns det några begränsningar i Access när det gäller antal poster? Kan man automatisera "reparera och komprimera" på servern på något sätt? Ska man byta system helt? Tacksam för fler tips.Sv: Databasen låst av en annan process
För att automatisera komprimeringen måste du skapa en schemalagd aktivitet på servern och det är knappast troligt att du får göra på ett webhotell.
Det låter väldigt konstigt att databasen växer så, det måste vara fel någonstans... När man bara lägger till poster och inte tar bort några ska databasen inte växa alls. Jag har flera liknande lösningar där det fungerar utan problem. Det måste nog vara något problem med din kod eller något på servern.
/JohanSv:Databasen låst av en annan process
Sv: Databasen låst av en annan process
/JohanSv:Databasen låst av en annan process
Sv: Databasen låst av en annan process
Att din fil växer låter mycket konstigt, det borde inte ske om inte t.ex. temporära poster skapas. Kolla på din kod om du hittar något konstigt.
/JohanSv:Databasen låst av en annan process
Sv: Databasen låst av en annan process
database.inc
<code>
<%
sFile = request.ServerVariables("PATH_TRANSLATED")
sSplit = split(sFile, "\")
for iCtr = 0 to uBound(sSplit) - 1
sDir = sDir & sSplit(ictr) & "\"
next
sConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sDir & "forum.mdb"
set conn = Server.CreateObject("ADODB.Connection")
set cmd = Server.CreateObject("ADODB.Command")
set rs = Server.CreateObject("ADODB.Recordset")
conn.mode = 3
conn.open sConnString
set cmd.activeconnection = conn
%>
</code>
ShowMessage.asp
<code>
<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--#include file = "database.inc"-->
<!--#include file = "FixSmileys.asp"-->
<%
'Uppdatera antalet visningar
StrUpdate = "UPDATE FORUM_MESSAGES SET ReadCount = ReadCount + 1 WHERE ID = " & Request.QueryString("ID")
conn.Execute(StrUpdate)
BolButton = False
'Räkna hur många "nästa meddelande" det finns
CountSQL = "SELECT COUNT(*) AS NumID FROM FORUM_MESSAGES WHERE ParentMessage = " & CLng(Request.Querystring("id"))
Set CountRS = conn.Execute(CountSQL)
'Hämta ID:t på "nästa meddelande"
If CountRS("NumID") = 1 Then
BolButton = True
IdSQL = "SELECT * FROM FORUM_MESSAGES WHERE ParentMessage = " & CLng(Request.Querystring("id"))
Set idRS = conn.Execute(IdSQL)
ForwardID = idRS("ID")
idRS.close : set idRS = nothing
End If
CountRS.close : set CountRS = nothing
sCaption = request.QueryString("Caption")
Function GetUrl(ByVal StrInput)
Dim mDelimit
Dim re
mDelimit = Chr(0)
Set re = New RegExp
re.Global = True
re.IgnoreCase = true
re.Pattern = "(\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+)"
StrInput = re.Replace(StrInput, "$1")
re.Pattern = "(http://|https://|ftp://|mailto:)(\S)(\S+)"
StrInput = re.Replace(StrInput, "$2" & mDelimit & "$3")
re.Pattern = "(www\.(\S)(\S+))"
StrInput = re.Replace(StrInput, "$1")
StrInput = Replace(StrInput, mDelimit, "")
GetUrl=StrInput
End Function
Function MessageChildren(ID, IndentLevel, iCurrentMessage)
dim oRs, oCmd, sSQL, sAns
'FIRST GET MESSAGE, TEXT, CLOSE
dim oParam
set oCmd = Server.CreateObject("ADODB.Command")
set oCmd.ActiveConnection = conn
oCmd.CommandText = "FORUM_MESSAGE"
oCmd.CommandType = 4
set oParam = cmd.CreateParameter("MESSAGEID", 3, 1)
oCmd.parameters.append oParam
oParam.value = cint(ID)
set oRs = oCmd.execute
set oParam = nothing
iIndent = IndentLevel
set oRs = oCmd.execute
if oRs.eof then
oRs.close
set oRs = Nothing
set oCmd = nothing
MessageChildren = ""
exit function
end if
sAns = "<TR><TD>"
for i = 0 to iIndent - 1
sAns = sAns & " "
Next
If CDate(Session("LastVisit")) < oRs("DatePosted") Then
sAns = sAns & " <font color=""#800000"">N</font> "
End If
if oRs("ID") <> cLng(iCurrentMessage) then
sAns = sAns & ""
sAns = sAns & oRs("Topic") & ""
else
sans = sans & "<B>" & oRS("Topic") & "</B>"
end if
sAns = sAns & "</TD><TD>"
DtPosted = oRs("DATEPOSTED")
If Date = CDate(Left(DtPosted,10)) Then
DtPosted = FormatDateTime(DtPosted,4) & " i dag"
Else
DtPosted = FormatDateTime(DtPosted,4) & " " & FormatDateTime(DtPosted,1)
End If
sAns = sAns & DtPosted
sAns = sAns & "</TD>"
sAns = sAns & "<TD>"
If oRs("AuthorEmail") <> "" Then
sAns = sAns & "" & oRs("AuthorName") & ""
Else
sAns = sAns & oRs("AuthorName")
End If
sAns = sAns & "</TD></TR>" & VbCrLf
oRs.close
sSQL = "SELECT ID FROM FORUM_MESSAGES WHERE PARENTMESSAGE = " & ID
oCmd.CommandText = sSQL
oCmd.CommandType = 1
set oRs = oCmd.execute
if ors.eof and iIndent = 0 then
sAns = ""
else
do while not oRs.eof
sAns = sAns & MessageChildren(oRs("ID"), iIndent + 1, iCurrentMessage)
oRs.MoveNext
Loop
end if
oRs.Close
set oRs = nothing
set oCmd = nothing
MessageChildren = sAns
End Function
iMessageId = request.QueryString("ID")
bValid = isNumeric(iMessageId) and iMessageId <> ""
if bValid then
cmd.CommandText = "Forum_Message"
cmd.CommandType = 4
set Param = cmd.CreateParameter("MESSAGEID", 3, 1)
cmd.parameters.append Param
Param.value = iMessageId
set rs = cmd.Execute
iThreadParent = rs("ThreadParent")
sMsg = rs("Comments")
end if
%>
<HTML>
<HEAD>
<TITLE>Cigarrprat</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="stilmall.css">
</HEAD>
<BODY>
<CENTER>
<!--#include file = "meny.htm"-->
</CENTER>
<%
if not bValid then
response.write "Du kan inte navigera på denna sida utan att ange en tråd. "
response.write "Gå tillbaka till forum index och försök igen."
response.end
end if
sTopic = rs("Topic")
%>
<% if sCaption <> "" then
response.write "<B><FONT COLOR = RED>" & sCaption & "</B></FONT><P>"
end if
%>
<TABLE>
<TR><TD>Ämne:</TD>
<TD><B><%= Server.HTMLEncode(rs("Topic")) %></B></TD></TR>
<TR><TD>Skrivet av:</TD>
<TD><B>
<%
If rs("AuthorEmail") <> "" Then
Response.write "" & Server.HTMLEncode(rs("AuthorName")) & ""
Else
response.write Server.HTMLEncode(rs("AuthorName"))
End If
%>
</B></TD></TR>
<TR><TD>Tid:</TD>
<TD><B><%= rs("DatePosted")%></B>
</TD></TR>
</TABLE><P>
<TABLE WIDTH = "95%"><TR><TD WIDTH = "100%">
<%
sMsg = Server.HTMLEncode(sMsg)
sMsg = replace(sMsg, vbcrlf, " <br>")
sMsg = replace(sMsg, " ", " ")
sMsg = GetUrl(sMsg)
sMsg = FixSmileys(sMsg)
Response.Write sMsg
%>
</TD></TR></TABLE>
<FORM ACTION = "reply.asp" METHOD = "POST">
<INPUT TYPE="HIDDEN" NAME="MessageID" VALUE="<%= iMessageID %>">
<INPUT TYPE="HIDDEN" NAME="ThreadID" VALUE="<%= iThreadParent %>">
<INPUT TYPE="HIDDEN" NAME="Topic" VALUE="<%= server.HTMLEncode(rs("Topic")) %>">
<INPUT TYPE="HIDDEN" NAME="OrigAuthor" VALUE="<%= server.HTMLEncode(rs("AuthorName")) %>">
<P align="center">
<input type="button" value="Backa" name="B2" onClick="self.location.href='javascript: history.go(-1)'">
<INPUT TYPE="Submit" NAME = "RequestReply" VALUE = "Svara">
<%
If BolButton = True Then
Response.Write " <input type=""button"" value=""Nästa"" name=""next"" onClick=""self.location.href='ShowMessage.asp?id=" & ForwardID & "'"">"
End If
%>
</FORM>
<%
rs.close
cmd.parameters.delete(0)
sThread = MessageChildren(iThreadParent, 0, iMessageID)
if sThread <> "" then
response.write "<HR><center><B>Hela tråden</B></center><P>" & vbcrlf
response.write "<TABLE WIDTH = '100%'>" & vbcrlf
response.write "<TR><TD><B>Ämne</B></TD>"
response.write "<TD><B>Tid</B></TD>"
response.write "<TD><B>Skrivet av</B></TD></TR>" & vbcrlf
response.write sThread
Response.Write "</TABLE>" & vbcrlf
end if
%>
<!--#include file = "database_cleanup.inc"-->
</body>
</HTML>
</code>Sv:Databasen låst av en annan process
/JohanSv: Databasen låst av en annan process
Sv:Databasen låst av en annan process
Sv: Databasen låst av en annan process
Sv:Databasen låst av en annan process
ParentMessage : Tal
ThreadParent : Tal
AuthorName : Text
AuthorEmail : Text
comments : PM
Topic : Text
ReplyCount : Tal
LastThreadPost : Datum/tid
DatePosted : Datum/Tid
ReadCount : Tal
IP : Text
ID : Räknare
Det enda som händer är att ReadCount uppdateras med +1 vid varje visning.Sv: Databasen låst av en annan process
Om det är index på någon av de andra kolumner finns det en liten risk att data uppdateras när du en annan kolumn i posten ändras.
Hade det varit SQL server hade jag kört Profilern för att se exakt vad som händer, vet inte om det finns liknande verktyg till Access.
En annan möjlighet är att kanske spegla hela databasen (exakt med design och allt) till SQL Server och sedan debugga ditt program mot den samtidigt som du kör Profilern, det skulle kanske ge något.
// Johan