Fork me on GitHub
#datomic
<
2022-12-18
>
Drew Verlee03:12:46

Why would the function datomic/create-database throw an exception? First off, help me understand if datomic/create-database is throwing. This is what part of my stack trace looks like:

[datomic.api$create_database invoke "api.clj" 22]
 [centriq_web.datomic.DatomicDB start "datomic.clj" 57]
What i see is in order 1, 2
[datomic.api$create_database invoke "api.clj" 22] <--- calls create database
 [centriq_web.datomic.DatomicDB start "datomic.clj" 57] <-- 1. our app 
So yeah, to me. it looks like it throws. However, given what i see in the logs, it looks like the uri i pass create-database is the correct uri for our database, e.g if i pass it locally it works. Would it throw if it couldn't use the uri from the aws ec2 instance the app is deployed to? I have a question on the https://forum.datomic.com/t/what-does-this-st-tell-me-is-wrong/2170 here with more details. My current theory is that it's a networking issue. But i would really like the stacktrace to say something even remotely like "can't reach or doesn't exist the thing your looking for" What i see instead, i guess is some repeated code in the stack trace (which makes sense given it's "retrying"). But what did it retry? Create database. i guess. But why did it have to retry? I guess it should couldn't find it right? I'm going to proceed assuming thats it 🐎 .

Joe Lane05:12:03

What version is your AWS Java SDK Dependency (e.g. DynamoDB), JDK version, and Datomic Version? The problem is in the stacktrace: > {:type java.lang.ClassNotFoundException > :message "com.amazonaws.retry.RetryMode" > :at [java.net.URLClassLoader findClass "URLClassLoader.java" 382]}]

Drew Verlee05:12:04

Thanks! I'll grab that information, its harder then it should be to sure. I assume the problem is described in the stacktrace, but i don't understand how. How i read the part you highlighted is "i wasn't able to find a function, maybe the url class loader" Then an unrelated message that isn't at all a message but just the words retry, implying that something was... retried. What do you read?

Drew Verlee06:12:53

jdk: openjdk8 datomic version:

[com.datomic/datomic-pro "0.9.5966" :exclusions [com.google.guava/guava commons-codec org.apache.httpcomponents/httpcore org.apache.httpcomponents/httpclient]]
is this the "aws java sdk? i don't see how that dynamodb related, but it looks to be the closest thing:
[com.amazonaws/aws-java-sdk-core "1.11.664" :exclusions [com.fasterxml.jackson.core/jackson-annotations com.fasterxml.jackson.core/jackson-databind]]
                 [org.sharetribe/aws-sig4 "0.1.3"]

Drew Verlee06:12:48

i'll be asleep soon. thanks for even looking at this 🙂 . Err if you don't have much time just get me your gut call on what the issue is, im thinking networking right now.

Drew Verlee06:12:09

also, your first thoughts on how to troubleshoot this kind of thing might be just, if not more helpful for me.

Joe Lane15:12:18

My read is: • Your apps call to d/create-database is the first time the AWS client is initialized (because it has to connect to DynamoDB) • When that happens, Datomic requires / imports the AWS and DynamoDB specific classes it needs. You can see that after [datomic.require$require_and_run invokeStatic "require.clj" 21] in the stacktrace. • Inside the datomic.aws namespace (per the stacktrace section w/ [datomic.aws__init <clinit> nil -1] ) , we attempt to load the class com.amazonaws.retry.RetryMode (not use it, just load the class) • Per the below message, we can't find the class.

{:type java.lang.ClassNotFoundException
  :message "com.amazonaws.retry.RetryMode"
  :at [java.net.URLClassLoader findClass "URLClassLoader.java" 382]}
Not sure if your (possibly transitive) deps changed recently but for some reason that that class is not on your classpath.

👀 1
Drew Verlee18:12:06

thanks for the perspective, i guess i had blocked the idea that it actually couldnt find the class because i'm not sure how we could have ended up there. But ill retrace my steps.

Joe Lane18:12:59

Before you create the database, try listing databases and see if you get the same result

jdkealy21:12:43

I tried to excise an attribute over 24 hours ago, and still don't see any changes.

{:db/excise :cart/session
 :db.excise/before #inst "2030"}

Joe Lane21:12:57

Have you run an indexing job? From https://docs.datomic.com/on-prem/reference/excision.html >> While the excise request itself is transactional, the excision operation is not transactional – the effect of excision is a background operation that occurs during the first indexing job after an excision transaction. More than one excision can occur between indexing jobs, and you should avoid attempting to repeatedly excise/requestIndex in an attempt to make excision feel synchronous. It's not. If you need to coordinate with a database that is guaranteed to have your excision, you can accomplish this with syncExcise.

jdkealy21:12:43

I called request-index, yes. Weirdly the attributes just went away.

jdkealy21:12:56

The transactor had restarted and the pods too, and now I see no references to the attribute I excised I'm doing a dry-run for a migration to a different stack, and I'd like to have a little more clarity. The old devs are giving the JVM 16GB of RAM due to performance issues that I zero'd in as stemming from this one attribute.

jdkealy21:12:30

I'm trying to get the RAM requirements down to 2GB. The stack dies when it hits this one query which has 80M records. A very simple query

(d/q '[:find ?e
       :in $ ?tip
       :where
        [?e :cart/session ?tip]]
        db-conn token)
with drastic consequences. Now that that's been excised, I'm down to 4-8GB RAM required.

Joe Lane23:12:09

How many results does that query return? Is that a Cardinality many attribute? Is that attribute indexed? Unique? What version of datomic are you running? You keep saying “required” but I’m not clear what that means to you. I understand cost saving, but why is getting the peer running with 2g an objective?

favila01:12:33

I assume this is a merely representative query and not the full query. But if it is the full query, consider using d/datoms and processing lazily if you need bounded memory use

favila01:12:50

Using only 2gb for a peer with ad hoc query loads is really aggressive

favila01:12:11

Peers are more like “read replicas” in a traditional sql db and should be sized accordingly, unless you have written queries very carefully with memory use and small intermediate result sets in mind

jdkealy17:12:30

Well, I want it down to 2GB in staging. Not immediately crashing with 2GB is a goal.

jdkealy17:12:39

We've already paid for reserve instances in AWS, and seeing slowness with 16GB of RAM. If we ever needed go beyond 16GB, we'd be in a lot of trouble. 2GB without crashing sounds like a reasonable goal to optimize for prod

Joe Lane18:12:32

"seeing slowness", there are more approaches than just adding RAM to improve Datomic Performance.

jdkealy21:12:22

Is there any way to see the status of the indexing job or to know when it's scheduled to run ?

Joe Lane23:12:58

You can check the logs and metrics