Read only tag history database connection

Hi, on my front end server I have a database connection to my tag history database. The user its using is read_only, I dont want someone to accidentally be able to write something to tag history from that server, ever.

There are no tags on that server that are set to historize any data, but I get the following message every minute in the logs:

ERROR: permission denied for table sqlth_drv

TagHistoryDatasourceSink	05Dec2024 18:37:22	There is a problem checking the tag history database tables during initialization of the store and forward engine which could prevent tag history data from being forwarded properly. Trying again in 60 seconds.
org.postgresql.util.PSQLException: ERROR: permission denied for table sqlth_drv

at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2725)

at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2412)

at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:371)

at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:502)

at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:419)

at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:194)

at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:155)

at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136)

at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136)

at com.inductiveautomation.ignition.gateway.datasource.SRConnectionWrapper$SRPreparedStatement.executeUpdate(SRConnectionWrapper.java:981)

at com.inductiveautomation.ignition.gateway.datasource.SRConnectionWrapper.runPrepUpdate(SRConnectionWrapper.java:181)

at com.inductiveautomation.gateway.tags.history.storage.TagHistoryDatasourceSink.loadOrCreateSystemDetails(TagHistoryDatasourceSink.java:486)

at com.inductiveautomation.gateway.tags.history.storage.TagHistoryDatasourceSink.getSystemDetails(TagHistoryDatasourceSink.java:436)

at com.inductiveautomation.gateway.tags.history.storage.TagHistoryDatasourceSink.initialize(TagHistoryDatasourceSink.java:299)

at com.inductiveautomation.ignition.gateway.history.sf.sinks.AbstractSink.tryToInit(AbstractSink.java:93)

at com.inductiveautomation.gateway.tags.history.storage.TagHistoryDatasourceSink.tryToInit(TagHistoryDatasourceSink.java:258)

at com.inductiveautomation.gateway.tags.history.storage.TagHistoryDatasourceSink.maybeInit(TagHistoryDatasourceSink.java:267)

at com.inductiveautomation.gateway.tags.history.module.TagHistoryProvider.queryAnnotations(TagHistoryProvider.java:193)

at com.inductiveautomation.ignition.gateway.sqltags.history.TagHistoryManagerImpl.queryAnnotations(TagHistoryManagerImpl.java:699)

at com.inductiveautomation.ignition.gateway.tags.model.ProjectDefaultTagManagerFacade.queryAnnotations(ProjectDefaultTagManagerFacade.java:453)

at com.inductiveautomation.perspective.gateway.components.PowerChartModelDelegate$AnnotationFetch.fetch(PowerChartModelDelegate.java:278)

at com.inductiveautomation.perspective.gateway.comm.FetchableCacheImpl.lambda$fetch$0(FetchableCacheImpl.java:47)

at com.inductiveautomation.perspective.gateway.threading.BlockingWork.invokeBlockingTask(BlockingWork.java:34)

at com.inductiveautomation.perspective.gateway.comm.FetchableCacheImpl.fetch(FetchableCacheImpl.java:47)

at com.inductiveautomation.perspective.gateway.comm.Routes.handleFetch(Routes.java:2375)

at com.inductiveautomation.ignition.gateway.dataroutes.Route.service(Route.java:254)

at com.inductiveautomation.ignition.gateway.dataroutes.RouteGroupImpl.service(RouteGroupImpl.java:64)

at com.inductiveautomation.ignition.gateway.dataroutes.RouteGroupCollectionServlet.serviceInternal(RouteGroupCollectionServlet.java:59)

at com.inductiveautomation.ignition.gateway.dataroutes.AbstractRouteGroupServlet.service(AbstractRouteGroupServlet.java:38)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)

at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1410)

at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)

at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1665)

at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)

at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:598)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)

at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1580)

at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)

at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)

at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)

at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)

at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)

at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)

at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at com.inductiveautomation.catapult.handlers.RemoteHostNameLookupHandler.handle(RemoteHostNameLookupHandler.java:121)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:301)

at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:51)

at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:141)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)

at org.eclipse.jetty.server.Server.handle(Server.java:563)

at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)

at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)

at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)

at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)

at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)

at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)

at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:558)

at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:379)

at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:146)

at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)

at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)

at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)

at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)

at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)

at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)

at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)

at java.base/java.lang.Thread.run(Unknown Source)

Is there anything I can do to stop this aside from turning off the logger? Is there a way to say hey this is a read only tag history connection? You might say to delete the tag history provider , but if I do that then it does not show up in the power chart historical tag browser as an option.

If I had to guess, this is because i have one local tag provider on that server, its trying to add that the gateway name and the 1 local tag provider to the _drv table in case someone ever enables history on a tag. So perhaps it would go away if I moved that tag provider off this server, but that would eliminate the purpose its serving, keeping some front end application data available there in case remote tag provider connections are lost.

similar error on Frontends with “query only” historian licenses that have connections to multiple historical provider DBs. I’ve even disabled S&F for them. Believe I’ve made the error disappear before with some combination of DB/historical provider/S&F toggling, but this is extra strange beacuse

  1. it appears to be trying to insert a NULL in the id column as an S&F test? - i guess that kinda makes sense though
  2. Ignition created the schema (that prevents NULLS) in the first place didn’t it?
  3. doesn’t happen on all (identically configured) Frontend gateways
StoreAndForward.Sink.TagHistoryDatasourceSink

There is a problem checking the tag history database tables during initialization of the store and forward engine which could prevent tag history data from being forwarded properly. Trying again in 60 seconds.

com.microsoft.sqlserver.jdbc.SQLServerException: Cannot insert the value NULL into column 'id', table 'IGN_HIST.dbo.sqlth_drv'; column does not allow nulls. INSERT fails.

EDIT - woudln’t you konw it as soon as i explained it, i though to simply toggle the historical provider and the error stopped flooding the logs. didn’t even delete the S&F cache, though I will for good measure